执行视图操作
我正在使用MVVM模式(使用MVVM Light)来构建我的XAML应用程序(win8)。 我有一个ListView,它绑定到我的ViewModel的属性。 我也有一个按钮触发该ViewModel上的操作,该操作更新该属性(这会导致更新ListView)。 该按钮使用命令在ViewModel上执行操作。 到现在为止还挺好。
问题是,刷新列表后,我需要执行严格属于我的View的操作,而不是ViewModel。 它应该将列表滚动到特定项目。 如何触发该操作? 我应该使用特定的ListView事件吗?
使用EventHandler
和ScrollIntoView(Object)
方法,您可以在不使用ViewMovel内的视图引用的情况下遵守MVVM模式,从而实现您想要的效果。
在你的ViewModel中像这样创建一个事件:
public event EventHandler ScrollListView;
在视图中添加一个回调以在属性更新时滚动ListView
:
ViewModel vm;
vm.ScrollListView += (sender, e) =>
{
var specificItem = **some item**;
MyListView.SelectedItem = specificItem;
MyListView.UpdateLayout();
MyListView.ScrollIntoView(MyListView.SelectedItem);
};
然后在ViewModel中更新该属性并且想要滚动ListView
:
if (this.ScrollListView != null)
{
this.ScrollListView(this, EventArgs.Empty);
}
当然,我通常会对每种情况做一些调整。
ViewModel可以将UI代码与UI设计(例如XAML)分离。 [设计师和开发者关心的分离,UI代码的自动化测试等]
理想情况下,视图的代码隐藏文件将是空的(除了对InitializeComponent的调用),并且ViewModel将处理所有UI逻辑和状态。 但是,在实践中,可能会有一些特定的UI操作无法单独由数据绑定来处理,因此您需要使用代码。 这样的代码应该放在代码隐藏中。
在你的情况下,(a)何时和(b)要滚动到哪个项目的逻辑必须在ViewModel中(而不是在视图中)。 只有在ListView中执行实际滚动所需的任何附加逻辑才会出现在View代码隐藏中。
是的,一个事件将是完成此操作的理想方式,以避免在ViewModel中引用View。 然而,我会建议在ViewModel中创建一个自定义事件(例如OnFirstItemInViewChanged,参数要滚动到的项目)以及View代码隐藏注册到此事件并只调用ListView.ScrollIntoView(item)。
注意:WinForms DataGridView有一个属性FirstDisplayedScrollingRowIndex。 如果在WPF ListView中有类似的东西,你可以通过将这个属性绑定到一个ViewModel属性来解决这个问题,因此让代码保持完全干净。
链接地址: http://www.djcxy.com/p/56135.html