就 WPF 中的 MVVM 而言,CollectionViewSource 的正确用法是什么?

问题描述

CollectionViewSource 类应该提供所谓的数据“视图”。这包括数据过滤、排序和分组。

现在,人们可能会认为,这是 MVVM 架构中 View 的职责,但通常是用户决定他想要什么样的分组、排序或过滤。这些是业务决策,属于视图模型。此外,过滤是通过获取一个元素并决定它是否与过滤器匹配来执行的,这绝对是 viewmodel 的责任(可能然后传递给服务)。

看来,CollectionViewSource 是直接从视图模型公开的一个很好的候选者,因为后者可以完全控制其属性(例如 GroupDescriptions)。但是即使这个类驻留在 Windows.Data 命名空间中,它仍然在 PresentationFramework 程序集中,我觉得从我的 BusinessLogic 程序集中引用它真的很不舒服,因为我几乎没有将它绑定到一个特定的(nomen omen) 表示框架。

据我所知,CollectionViewSource 最常见的地方是控件(窗口的)资源,我可以(令人惊讶地)从中绑定到视图模型。但是随后操作过滤、排序和分组是一团糟,因为您必须在视图和视图模型之间手动推送信息。举个例子:

<CollectionViewSource x:Key="SuggestionItems" Source="{Binding Suggestions}">
  <CollectionViewSource.GroupDescriptions>
    <PropertyGroupDescription PropertyName="{Binding SuggestionGroupByProperty}"/>
  </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

这行不通,因为 PropertyGroupDescription.PropertyName 不是 DependencyProperty。所以我可能必须设计我自己的 Xaml 扩展才能将这些信息从视图模型绑定到视图。

我没有找到任何关于 ColletionViewSource 应该如何适应 MVVM/WPF 框架的教程或文档。实际上,我的印象是,这并没有经过深思熟虑,因为例如,将 CollectionViewSource 放在资源外部的任何位置需要一些非常讨厌的恶作剧来简单地将集合推入内部。

例如(注意 SelectedItem):

<DataGrid x:Name="grid" 
          AutoGenerateColumns="False" 
          ItemsSource="{Binding}" 
          SelectedItem="{Binding Path=DataContext.SelectedItem,RelativeSource={RelativeSource AncestorType={x:Type Window}},Mode=TwoWay}">
  <DataGrid.DataContext>
    <CollectionViewSource x:Name="myViewSource" Source="{Binding MyCollection}" Filter="CollectionViewSource_OnFilter">
      <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="Container" />
      </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
  </DataGrid.DataContext>
  <!-- (...) -->
</DataGrid>

那么 CollectionViewSource 应该如何规范地适应 MVVM 模式,以便视图模型对其有足够的控制权?如果不应该,那么这个场景(集合分组、排序、过滤)在 MVVM 中应该如何实际显示

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)