What is the WPF equivalent of Silverlight's ScrollViewer.ScrollIntoView?
The FrameworkElement class implements a BringIntoView() method - if you are dealing with a class that inherits from FrameworkElement you should be able to call that method. The method essentially raises the RequestBringIntoViewEvent which will bubble up the visual tree. The ScrollViewer and a bunch of other classes handle the event and then call their internal logic to bring the element into view.
Also some ItemControls such as DataGrid or ListBox provide a ScrollIntoView() method to make a child visible.
The ScrollIntoView() in turns calls the OnBringItemIntoView method in the ItemsControl class and in turn calls the FrameworkElement but also deals with a VirtualizingPanel where you might not have a FrameworkElement already created.
Related
ObjectProvider has the ability to bind the method of the class to the property of the Control.
If then is there a functionality to bind the method of the Control to the method of the ViewModel?
I would like to create a structure which if the method of the ViewModel is called then the method of the Control is called. (because the method of the ViewModel connected with the method of the Control)
Is there any class built-in WPF that supports this functionality?
I think you are looking for the ICommand Interface.
I have a main window that contains two usercontrols.
The first usercontrol have a tabcontrol.How can I notify the second usercontrol when a tabitem is selected in the first usercontrol.
If you're using MVVM approach, you'll probably have bound SelectedIndex of your TabControl to a ViewModel property. In that case your second usercontrol will bind to the same (or some other) property of the ViewModel and will be notified through standard notification mechanisms (such as INotifyPropertyChanged or DependencyProperty etc.).
In case, you are not using ViewModels and coding directly behind your Window, you can listen to SelectionChanged event and update your second usercontrol therein.
I'm using MVVM Pattern (with MVVM Light) to build my XAML app (win8). I have a ListView, which is bound to a property of my ViewModel. I also have a button that triggers an operation on that ViewModel, which updates that property (which results in updating the ListView). The button uses commanding to execute the operation on the ViewModel. So far so good.
The problem is that after the list is refreshed I need to perform an operation that strictly belongs to my View, not to the ViewModel. It should scroll the list to a specific item. How to trigger that operation? Should I use a specific ListView event?
Using an EventHandler and the ScrollIntoView(Object) method you can achieve what you want without using references of the View inside the ViewMovel and respecting MVVM pattern.
Create an event in your ViewModel like this:
public event EventHandler ScrollListView;
In your View add a callback to scroll the ListView when the property is updated:
ViewModel vm;
vm.ScrollListView += (sender, e) =>
{
var specificItem = **some item**;
MyListView.SelectedItem = specificItem;
MyListView.UpdateLayout();
MyListView.ScrollIntoView(MyListView.SelectedItem);
};
Then in your ViewModel when you update that property and want to scroll the ListView:
if (this.ScrollListView != null)
{
this.ScrollListView(this, EventArgs.Empty);
}
This is how I usually do with some tweaks for each case of course.
The ViewModel is there to decouple the UI Code from the UI Design (E.g. XAML). [Separation of Concerns of Designer and Developer, Automated testing of UI Code, etc]
Ideally the code-behind file of the View will be empty (except the call to InitializeComponent) and all UI logic and state will be handled by the ViewModel. However, in practice there might be some specific UI manipulation that cannot be handled by data-binding alone and you will need to resort to code. Such code should be placed in the code-behind.
In your case, the logic for (a) when and (b) which item to scroll to must be in the ViewModel (not in the View). Only any additional logic required to perform the actual scrolling in the ListView will be in the View code-behind.
Yes, an event would be the ideal way to do this, to avoid having any references to the View inside the ViewModel. I would recommend however to create a custom event in the ViewModel (e.g. OnFirstItemInViewChanged with arguments the item to scroll to) and in the View code-behind register to this event and just call ListView.ScrollIntoView(item).
Note:
WinForms DataGridView had a property FirstDisplayedScrollingRowIndex. If there was something similar in WPF ListView, you could solve this by binding this property to a ViewModel property, therefore leaving the code-behind completely clean.
I'm building a pos system that has a main ContentControl to display different screens of the application. I use DataTemplates to map my viewmodels to views. To navigate between the different views displayed in the ContentControl I'd like to store a screenshot of the UserControl in the viewmodel when the UserControl is unloaded (or the ContentControl changes).
I posted a related question here WPF Binding FrameworkElement event to command in which I attempted to bind a command to FrameworkElement.Unloaded but that doesn't work (see answer at that link)
Is this possible without breaking the MVVM pattern?
here is a nice link to how to do a screenshot in wpf.
here is what i would do:
my mainviewmodel which handle the navigation should expose an event and raise this event before you set the new contentviewmodel. the old contentviewmodel should be in the eventargs. in your mainwindow codebehind you subscribe to the event(not breaking mvvm here). when ever this event is raise you can call the screenshot method and put the result to the oldviewmodel.
edit:
mainwindow codebehind
void NavigationChangingEvent(object sender, NavChangingArgs args)
{
var oldvm = args.ChangingViewmodel;
oldvm.Screenshoot = this.mycontentcontrolwheremyviewmodelareshown.GetJpgImage(1, 90);
}
I have a class that needs to notify that something significant has occurred. The class is in a WPF-project, even though this specific class, is lookless (and doesn't inherit from UIElement, neither directly or indirectly).
Normally, I just register a RoutedEvent to get this functionality but as this class neither has AddHandler nor RemoveHandler, I can't get it to work. Anyone knows of another way of get the RoutedEvent behaviour?
As far as I know, if your class isn't a UIElement, it cannot be part of the visual tree, and if it isn't part of the visual tree, you cannot throw RoutedEvents. They're strictly a UI concept.
I think the recommended approach would be to either make your class inherit from UIElement, or if that's not possible/desired, create a counterpart for your class which does inherit from UIElement and use this second class in the visual tree where you would normally place your original class.