2012-03-05 80 views
11

ObservableCollection支持操作如AddRangeRemoveRange造成的潜在问题是什么?由于ObservableCollection经常与WPF一起使用,所以微软不提供它们是必然的原因。为什么ObservableCollection不支持批量更改?

您可以实现自己的支持批量操作的集合并实现INotifyCollectionChanged。如果我将这样的控件绑定到ItemsControl会发生什么?

有谁知道ItemsControls不支持批量更改?

+6

有在Microsoft.VisualStudio.Language一个BulkObservableCollection类工作的集合。 Intellisense.BulkObservableCollection http://msdn.microsoft.com/en-us/library/dd867973.aspx – tofutim 2012-11-21 14:37:58

回答

3

我不认为这是有任何潜在的缺点或问题,它只是它不存在。事实上,你会发现'System.Collections.Generic'中的大多数类型都不提供'AddRange'功能。

同时,很多人已经创建了自己的'ObservableCollection'版本来提供您想要的功能。INotifyCollectionChanged包含足够的信息,使其处理程序可以记录一系列项目可能因此受到影响的时间。

最后但并非最不重要的,如果你绑定具有这些“范围”类型的操作,你会发现,他们将与您的用户界面按预期

4

ObservableCollection有很多扩展可以在互联网上找到,添加添加/删除范围的概念,或允许您推迟更新并手动触发它们。例如看到这个堆栈溢出问题:

ObservableCollection Doesn't support AddRange method, so I get notified for each item added, besides what about INotifyCollectionChanging?

您还可以实现批量添加触发一个复位事件,这将导致UI重新呈现所有集合中的项目:

http://peteohanlon.wordpress.com/2008/10/22/bulk-loading-in-observablecollection/

这些允许您更有效地管理UI更新。 ItemsControl如何处理集合已更改的事件,其中详细列出了已更改的项目取决于WPF框架本身。我假设它能够智能地处理这个问题!

我对您的建议是,如果性能对您至关重要,并且您的许多项目正在更新并遇到性能问题,那么子类ObservableCollection将以最适合您应用程序需求的方式管理收集更改通知。

+0

快速浏览一下链接问题的实现,显示效率低下的实现。基本上,为每个添加的项目引发'CollectionChanged'事件,然后再次重置集合! – 2012-03-05 17:12:25

+1

@KentBoogaart嗨肯特,你的意思是回答这个问题吗?我看起来很好。 AddRange方法遍历所添加的项目,然后触发一个CollectionChanged事件,其中更改类型为“add”,提供添加项目的列表。虽然代码的格式不是很好;-)由于RangeObservableCollection扩展了ObservableCollection,因此在每个项目上调用Add都会导致为每个添加的项目引发CollectionChangedEvent,因此它的格式不太好.-) – ColinE 2012-03-05 17:15:59

+1

然后,在添加所有项目后,通过重置集合来浪费所有这些努力。 – 2012-03-05 18:19:27

2

NotifyCollectionChangedEventArgs包括索引信息。删除项目会导致索引重新洗牌,就像插入项目一样。因此,尽管不是完全不可能的,但提供使用范围的能力将是相当困难的并且可能是低效的。

+0

唯一的索引信息是“发生变化的索引”。这些信息很容易通过添加和删除范围操作来提供。 – 2012-03-05 18:34:17

+0

@ A.R .:不,如果我删除集合的第一个和最后一个项目,该怎么办?事件参数中只有一个索引,但两个索引是必需的。 – 2012-03-05 18:39:26

+0

有两个索引。有'NewStartingIndex'和'OldStartingIndex'。后者的描述是:“获取移动,移除或替换动作发生的索引”。另外,除非要删除集合中的所有项目,否则您描述的场景是不可能的,因为范围内的元素是连续的。 – 2012-03-05 18:49:59

1

必须有一个原因,微软并没有为他们提供

它们不提供一切可能的一项功能,它(也)对需求的东西成本。

您可以实现自己的支持批量操作的集合并实现INotifyCollectionChanged

是的。当你这样做时,你会发现该集合将不得不做出选择以何时/何时传播这些更改。我从来没有尝试过,但我认为View或ViewModel可以做出比可重复使用的集合更好的决策。