executing view operations

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 (Eg 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 (eg 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.

链接地址: http://www.djcxy.com/p/56136.html

上一篇: MVVM RelayCommand可以执行

下一篇: 执行视图操作