c# - 就WPF中的MVVM而言,CollectionViewSource的正确用法是什么?
问题描述
CollectionViewSource
类应该提供所谓的数据“视图”。这包括数据过滤、排序和分组。
现在,有人可能会认为,这是 MVVM 架构中视图的责任,但通常是用户决定他想要什么样的分组、排序或过滤。这些是业务决策,属于 viewmodel。此外,过滤是通过获取一个元素并决定它是否匹配过滤器来执行的,这绝对是 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 模式,以便 viewmodel 对其有足够的控制权呢?如果不应该,那么这个场景(集合分组、排序、过滤)在 MVVM 中应该如何实际看待?
解决方案
推荐阅读
- apache-kafka - 在 kafka 中向许多应用程序发送消息的最佳实践
- debezium - 如何使用 java 捕获 Embedded-debezium 数据库连接失败?
- python - MongoDB将增量添加到id
- tensorflow - TensorFlow Object Detection 在同一模型检查点的两次评估中得到不同的结果
- c++ - 需要了解如何在循环中添加值
- unity3d - mono_assembly_open 和 mono_image_open_from_data_with_name 有什么区别?
- css - 在 Bootstrap 的 jumbotron 中放置响应式文本
- tensorflow - 在具有更多元素的矩阵上调用正交初始化器:可能会导致缓慢
- c++ - 是否可以制作一个包含无符号整数的数组?
- java - 一键更新所有屏幕活动