【问题标题】:MVVM pattern - executing view operationsMVVM 模式 - 执行视图操作
【发布时间】:2013-05-03 00:00:53
【问题描述】:

我正在使用 MVVM 模式(带有 MVVM Light)来构建我的 XAML 应用程序 (win8)。我有一个 ListView,它绑定到我的 ViewModel 的一个属性。我还有一个按钮可以触发对该 ViewModel 的操作,该操作会更新该属性(这会导致更新 ListView)。该按钮使用命令对 ViewModel 执行操作。到目前为止一切顺利。

问题是列表刷新后我需要执行一个严格属于我的视图的操作,而不是视图模型。它应该将列表滚动到特定项目。如何触发该操作?我应该使用特定的 ListView 事件吗?

【问题讨论】:

    标签: wpf xaml mvvm windows-8 mvvm-light


    【解决方案1】:

    使用EventHandlerScrollIntoView(Object) 方法,您无需在ViewMovel 中使用View 的引用并尊重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);
    }
    

    当然,这就是我通常对每种情况进行一些调整的方式。

    【讨论】:

      【解决方案2】:

      ViewModel 用于将 UI 代码与 UI 设计(例如 XAML)分离。 [设计师和开发人员的关注点分离,UI代码的自动化测试等]

      理想情况下,视图的代码隐藏文件将为空(对 InitializeComponent 的调用除外),所有 UI 逻辑和状态都将由 ViewModel 处理。但是,在实践中,可能有一些特定的 UI 操作无法单独通过数据绑定处理,您将需要求助于代码。这样的代码应该放在代码隐藏中。

      在您的情况下,(a)何时和(b)滚动到哪个项目的逻辑必须在 ViewModel 中(而不是在 View 中)。只有在 ListView 中执行实际滚动所需的任何附加逻辑才会在 View 代码隐藏中。

      是的,事件将是执行此操作的理想方式,以避免在 ViewModel 中对视图有任何引用。但是,我建议在 ViewModel 中创建一个自定义事件(例如 OnFirstItemInViewChanged 带有要滚动到的项目的参数),并在 View 代码隐藏中注册到该事件并调用 ListView.ScrollIntoView(item)。

      注意: WinForms DataGridView 有一个属性 FirstDisplayedScrollingRowIndex。如果 WPF ListView 中有类似的东西,您可以通过将此属性绑定到 ViewModel 属性来解决此问题,从而使代码隐藏完全干净。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多