MVVM 中的 ICollectionView 和 CollectionViewSource

问题描述 投票:0回答:1

我正在学习 .NET 和 WPF,同时构建一个小型待办事项列表(如应用程序)。

我试图了解 ICollectionView 接口和 CollectionViewSource 如何与 MVVM 模式一起使用,而不破坏它。据我所知,它们是 WPF 类型,并且在 ViewModel 中使用它们将 View 和 ViewModel 强耦合在一起。

我的应用程序主要是一个数据网格,其中有一些包含命令的按钮。 ViewModel 内的命令调用一个分配结果的方法,并使用

CollectionViewSource.GetDefaultView(Object).MoveCurrentToNext()

移动到下一行

视图模型

public RelayCommand TestPassedCommand => new RelayCommand(execute => TestPassed(), canExecute => SelectedItem != null);
private void TestPassed()
{
    if(_selectedItem != null)
    {
        _selectedItem.Result = ResultEnum.passed;
    }
    ICollectionView view = CollectionViewSource.GetDefaultView(HardwareTests);
    view.MoveCurrentToNext();
}

我尝试过的

我删除了调用方法

MoveCurrentToNext()
的部分代码,并在代码隐藏中添加了一个EventHandler(这也破坏了MVVM)。单击按钮时,在上面的命令之前执行事件处理程序,尽管它仍然有效,但我不喜欢这种方法。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        
    }

    private void MarkTestPassed(object sender, RoutedEventArgs e)
    {
        if(DataGrid.SelectedItem != null)
        {
            ICollectionView view = CollectionViewSource.GetDefaultView(DataGrid.ItemsSource);
            view.MoveCurrentToNext();
        }
    }
}
c# wpf mvvm
1个回答
0
投票

无论您是否想在视图模型类中使用

CollectionViewSource
,这完全取决于个人设计选择。 MVVM 不关心这种情况。

“我读过它们是 WPF 类型,并且在 ViewModel 中使用它们与视图强耦合”

仔细想想,这没有道理。您似乎认为所有 WPF 类型都与视图相关。事实并非如此。视图模型类中使用的最著名的类型是

INotifyPropertyChanged
。如果视图模型类型引用视图类型,则视图模型与视图之间只会存在强耦合。 WPF 类型既不是视图类型也不是视图模型类型。它们首先是框架类型。使用框架类型只能创建与框架的强耦合,这通常是您想要的,因为这就是框架的工作方式(IoC)。 在 MVVM 中,一切都与责任有关。当控件呈现并与用户交互时,视图模型不允许实例化控件,这是应用程序视图的责任。这是关键标准,而不是事实,例如
StackPanel
是 WPF 类型。

“我删除了调用 MoveCurrentToNext() 方法的部分代码,并在代码隐藏中添加了一个 EventHandler(这也破坏了 MVVM)。”

你从哪里学来的? Microsoft 从未将代码隐藏与 MVVM 设计模式相关。根据定义,设计模式必须与语言和编译器无关。代码隐藏是一种通过部分类概念实现的语言功能。
MVVM 不关心您是否使用 XAML、C#、VB.NET 还是 C。它只关心应用程序结构、构成该结构的组件(视图、视图模型、模型)之间的依赖关系以及定义是否类型与视图、视图模型或模型应用程序组件相关联。 MVVM 不关心你使用的是命令还是事件。但它关心视图模型中的命令是否执行视图相关的职责,例如显示一个对话框。

如果您的事件处理程序没有因为执行错误的职责而破坏 MVVM,那么它也不会破坏 MVVM。事件处理程序本身不是问题。事件处理程序所做的就是相关的。

“我试图了解 ICollectionView 接口和 CollectionViewSource 如何与 MVVM 模式一起使用,而不破坏它。”

CollectionViewSource
是一个辅助类,是获取视图模型类集合的默认集合视图的唯一方法(
ItemsControl.Items
当然不是一个选项,因为这会破坏 MVVM)。
一般来说,在视图模型组件中处理集合视图是完全没问题的。如果您不希望视图模型类中存在对
CollectionViewSource
的依赖,那么应该清楚这是一个与 MVVM 无关的设计决策。

通常,您使用

ICollectionView
对集合进行排序、过滤和分组。这些集合操作是否属于视图或视图模型取决于上下文。关键是视图或尤其是控件应该与数据无关。
DataGrid
可以在不知道数据类型的情况下执行基本排序。按属性排序需要这些知识,因此通常在存在这些知识的视图模型中实现。并且您始终可以在视图组件中获取默认的
ICollectionView
并将其传递给视图模型组件。使用
CollectionViewSource
还允许在 XAML 中定义排序描述。

无论您是否想在视图模型类中使用

CollectionViewSource
,这完全取决于个人设计选择。 MVVM 不关心这种情况。

© www.soinside.com 2019 - 2024. All rights reserved.