我应该绑定到ICollectionView还是ObservableCollection


83

一个应该绑定DataGrid

ICollectionView = CollectionViewSource.GetDefaultView(collection)

或到

ObservableCollection<T> collection; ???

MVVM的最佳做法是什么,为什么?

Answers:


129

总是绑定到ICollectionView,不管你让它明示或没有。

假设我们有

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

在这种情况下,绑定到collectioncollectionView相同:绑定引擎将绑定到默认集合视图(引用等于collectionView)(如果您告诉它绑定到)collection

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

只是要清楚一点:即使直接绑定到集合,绑定引擎也会绑定到默认视图。修改视图的属性(例如排序条件)将影响似乎直接绑定到集合的绑定,因为在幕后,它是默认视图的绑定。

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

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


1
很棒的答案。我自己的偏好是现在绑定到ObservableCollection,因为它是System.Collections的一部分,并且“感觉”更多地代表了我所代表的关于模型的某些东西,而不是与View相对的东西,但是MVVM有时这种方式有点麻烦。
2011年

很好的答案。我只想指出,在Silverlight中,除非绑定集合实现ICollectionViewFactory,否则不会为绑定集合创建默认的CollectionView。
2012年

这也/仍然适用于通用应用吗?
罗伯特·麦克莱恩

@RobertMacLean:我没有任何WP开发经验,所以很遗憾没有想法。
2014年

要在xaml中为基础集合创建显式视图,请在参考资料中创建CollectionViewSource元素。具有CollectionViewSource.Source属性绑定到基础集合。然后将您的ItemsControl.ItemSource属性绑定到您通过StaticResource在资源中创建的CollectionViewSource。这样,应用于一个视图的排序/筛选/分组操作不会“污染”绑定到默认CollectionView的其他ItemsControl。
Frank Liu

35

ObservableCollection<T>实现,INotifyCollectionChanged并在更改集合中的项目时通知UI。

ICollectionViewINotifyCollectionChanged如果基础集合实现了传播事件,那么除了传播事件外,您还可以对集合进行过滤,排序或分组。

只要绑定到MVVM,这两种类型都可以很好地工作。使用ICollectionView时,你需要排序,筛选,或分组。不使用时ObservableCollection<T>直接使用。


另一篇文章似乎与ICollectionView会根据集合更改事件自动获取更新相矛盾……这是错误的吗?stackoverflow.com/a/17906474/3195477
UuDdLrLrSs

@UuDdLrLrSs如果修改了集合中的项目,则绑定到这些项目的UI或那些项目的属性将更新,而无需在集合上调用Refresh。另一篇文章专门询问更改集合中项目的属性,并自动触发ICollectionView的刷新以确保它仅包含仍符合过滤条件的项目。根据另一篇文章中的答案,您将必须调用Refresh()方法来更新集合中项目的“列表”。
Jimmie R. Houts

9

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

其他选择是使用ICollectionView和使用实现该类的类,但它不是WPF本身的一部分。


1
但这并不是主要区别。注意wpf标签。“ [[如果]绑定控件需要对当前项目,过滤器和公司具有不同的概念,那么您想要的是显式绑定到同一基础集合的多个视图”。那是区别。不管是什么,成为“纯粹主义者”意味着您无法过滤等。请参见Jimmie Houts答案,该答案侧重于更清晰语言的实际差异。
德克·贝斯特

7

我不认为它必须做任何事情MVVMICollectionView如果需要,则提供额外的功能,如排序分组等,IColectionView否则只需使用ObservableCollection


2

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.