WPF:将项目添加到ListView的最有效/最快的方法是什么?

时间:2010-07-22 02:33:58

标签: wpf performance

我需要以相当高的频率添加网格中的大量行(在某些情况下,每秒最多10行) 我选择了ListView,因为我认为它是WPF中最快的网格控件。 (当然比GridView快很多)

在添加了几十万个项目并且它们继续进入后,CPU利用率变得非常高。这是相当令人惊讶的,因为ListView只呈现可见行,所以总共添加了多少都无关紧要。

我的第一种方法是将它绑定到ObservableCollection但过了一会儿,CPU利用率上升,整个Window变得紧张。

我尝试将它绑定到常规List,这似乎更快,但是我确实需要经常调用列表中的.Refresh(),这也会在一段时间内扼杀CPU。

比我尝试subclassing ObservableCollection块插入希望批处理可以提高性能/减少cpu工作量,但这种方法似乎需要调用CollectionView.Refresh,这与调用集合上的Reset()相同,并且当集合中有很多项目时,也是无效的。

清除observablecollection并调用myListView.Items.Refresh()将其恢复为0会将cpu使用带回到起始点。

这里的想法开始耗尽..再次,我的目标是,添加/显示大量项目并以最高性能的方式显示8列网格.ListView看起来不错,只需要有一些方法我可以进一步调整它..

更新

分析后,ObservableCollection在网格中有800k行,最多的cpu工作是通过以下方式完成的:

  • (75%)System.Windows.Media.MediaContext.RenderMessageHandler(object resizedCompositionTarget)
  • (20%)ObservableCollection.OnCollectionChanged(NotifyCoolectionChanged ..)

虽然取决于会话,这些数字差别很大..

UPDATE 2 ..确定BindingList似乎是明显的赢家。

这里是结果(以刻度表示)并排,每行100万行(每秒添加10个项目):

的ObservableCollection: http://i.imgur.com/7ZoSv.png

的BindingList http://i.imgur.com/jm5qF.png

你可以看到CPU活动的总体下降,以及在Binding List案例中处理树所需的大约一半的滴答!感谢Akash这个好主意。

1 个答案:

答案 0 :(得分:19)

我会建议BindingList类,而不是使用ObservableCollection,你可以这样做..

BindingList<string> list = new BindingList<string>();

list.AllowEdit = true;
list.AllowNew = true;
list.AllowRemove = true;

// set the list as items source
itemCollection.ItemsSource = list;

// add many items...

// disable UI updation
list.RaiseListChangedEvents = false;

for each(string s in MyCollection){
   list.Add(s);
}

// after all.. update the UI with following
list.RaiseListChangedEvents = true;
list.ResetBindings(); // this forces update of entire list

你甚至可以批量启用/禁用更新,而不是一次性添加所有内容,BindingList在我的所有UI中运行得比ObservableCollection更好,我想知道为什么当BindingList真正取代ObservableCollection时,每个人都会谈论更多关于ObservableCollection。