代码之家  ›  专栏  ›  技术社区  ›  Sonic Soul

WPF:向ListView添加项的最有效/最快速的方法是什么?

  •  16
  • Sonic Soul  · 技术社区  · 15 年前

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

    CPU利用率变得相当高后,几十万个项目被添加,他们继续进来。这是相当令人惊讶的,因为ListView只呈现可见的行,所以不管总共添加了多少行。

    我的第一种方法是将它绑定到ObservaleCollection,但是过了一段时间,CPU利用率提高了,整个窗口变得不稳定。

    但是我确实需要经常调用列表上的.Refresh(),这会在一段时间后也会使CPU崩溃。

    比我想的要多 subclassing ObservableCollection

    清除observablecollection,然后调用myListView.Items.Refresh()将其恢复为0,这将使cpu使用率恢复到起点。

    更新

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

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

    尽管这些数字因会话而异。。

    可观测集合: http://i.imgur.com/7ZoSv.png

    绑定列表 http://i.imgur.com/jm5qF.png

    您可以看到CPU活动的总体下降,以及在绑定列表情况下处理树所需的大约一半时间!感谢阿卡什给我这个好主意。

    1 回复  |  直到 9 年前
        1
  •  22
  •   Akash Kava    15 年前

    我建议使用BindingList类,而不是使用observeCollection,您可以这样做。。

    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中都比ObservaleCollection运行得更好,我想知道为什么在BindingList真正超越ObservaleCollection的时候,到处都有人谈论ObservaleCollection。