我应该绑定到 ICollectionView 还是 ObservableCollection

Posted

技术标签:

【中文标题】我应该绑定到 ICollectionView 还是 ObservableCollection【英文标题】:Should I bind to ICollectionView or ObservableCollection 【发布时间】:2011-09-13 03:44:54 【问题描述】:

是否应该将DataGrid 绑定到

ICollectionView = CollectionViewSource.GetDefaultView(collection)

还是去

ObservableCollection<T> collection;???

MVVM 的最佳实践是什么?为什么?

【问题讨论】:

【参考方案1】:

总是绑定到ICollectionView,无论您是否明确表示。

假设我们有

var collection = new ObservableCollection<string>();
var collectionView = CollectionViewSource.GetDefaultView(collection);

在这种情况下,绑定到collectioncollectionView 是相同的:如果您告诉绑定引擎绑定到默认集合视图(引用等于collectionViewcollection.

这意味着您的问题的答案是“绝对没有区别”。

完全清楚:即使您直接绑定到集合,绑定引擎也会绑定到默认视图。修改视图的属性(例如排序条件)将影响看起来直接绑定到集合的绑定,因为在幕后它是到默认视图的绑定。

但是,还有另一个有趣且相关的问题:应该绑定到默认集合视图(即集合本身,因为没有理由显式绑定到默认视图)还是同一集合的另一个视图?

考虑到每个视图都有自己的当前项目、排序标准等概念,因此如果您打算对同一个集合进行多个绑定,并且绑定控件需要具有不同的当前项目、过滤器和公司,那么您想要的是显式绑定到同一底层集合的多个视图。

【讨论】:

很棒的答案。我自己的偏好是绑定到 ObservableCollection,因为它是 System.Collections 的一部分,并且“感觉”更能代表我所代表的关于模型而不是视图的东西,但 MVVM 有时会以这种方式敏感。 很好的答案。我只想指出,在 Silverlight 中,不会为绑定集合创建默认 CollectionView,除非该绑定集合实现 ICollectionViewFactory。 这是否也/仍然适用于通用应用程序? @RobertMacLean:我没有任何 WP 开发经验,所以很遗憾不知道。 要在 xaml 中为基础集合创建显式视图,请在资源中创建一个 CollectionViewSource 元素。将 CollectionViewSource.Source 属性绑定到基础集合。然后将您的 ItemsControl.ItemSource 属性绑定到您通过 StaticResource 在资源中创建的 CollectionViewSource。这样,应用于一个视图的排序/过滤/分组操作不会“污染”绑定到默认 CollectionView 的其他 ItemsControl。【参考方案2】:

ObservableCollection&lt;T&gt; 实现 INotifyCollectionChanged 并在集合中的项目发生更改时通知 UI。

ICollectionView 将使您能够过滤、排序或分组集合,如果基础集合实现了INotifyCollectionChanged 事件,则除了传播它。

只要绑定到 MVVM,这两种类型都可以很好地工作。当您需要排序、过滤或分组时,请使用ICollectionView。不使用时直接使用ObservableCollection&lt;T&gt;

【讨论】:

这篇其他帖子似乎与 ICollectionView 将根据集合更改事件自动更新......这是不正确的吗? ***.com/a/17906474/3195477 @UuDdLrLrSs 如果集合中的项目被修改,绑定到这些项目的 UI 或这些项目的属性将更新,而无需对集合调用 Refresh。另一篇文章专门询问更改集合中项目的属性并自动触发刷新 ICollectionView 以确保它仅包含仍符合过滤条件的项目。根据另一篇文章中的答案,您必须调用 Refresh() 方法来更新集合中项目的“列表”。【参考方案3】:

只是为了补充乔恩所说的话。主要区别在于,通过使用CollectionViewSource.GetDefaultView(collection),您使 ViewModel 依赖于 WPF。许多 MVVM 纯粹主义者不喜欢这样,这将使 ObservableCollection 成为唯一有效的选项。

其他选项是使用ICollectionView 并使用一个实现它的类,但它不是 WPF 本身的一部分。

【讨论】:

这不是主要区别。注意 wpf 标签。 “[如果]绑定控件需要具有当前项目、过滤器和公司的不同概念,那么您想要的是显式绑定到同一基础集合的多个视图”。这就是区别。作为一个“纯粹主义者”,无论是什么,都意味着你不能过滤等。请参阅 Jimmie Houts 的回答,该回答侧重于更清晰语言的实际差异。【参考方案4】:

我不认为它与MVVM 本身有任何关系。 ICollectionView 提供附加功能,如排序分组等,如果您需要这些功能,请使用IColectionView,否则只需使用ObservableCollection

【讨论】:

【参考方案5】:

如果您希望网格显示应用于视图的设置,您将绑定到视图,例如过滤,否则视图是多余的。

【讨论】:

以上是关于我应该绑定到 ICollectionView 还是 ObservableCollection的主要内容,如果未能解决你的问题,请参考以下文章

将DataGrid标头中的Button绑定到ViewModel

WPF 的 ICollectionView.filter 与大量数据集

如何使用 ICollectionView 过滤 wpf 树视图层次结构?

获取 ICollectionView 的 Count 属性

CollectionViewSource、ICollectionView、ListCollectionView、IList 和 BindingListCollectionView 及其用例有啥区别?

获取ICollectionView的Count属性