2012-10-11 62 views
4

我已經使用listView.BeginUpdate()listView.EndUpdate(),但是當我刪除例如25k中的100個項目時,仍然需要10秒。如何加速Winforms ListView項目刪除?

任何想法,訣竅,使其更快?

編輯:

this.listView.BeginUpdate(); 
for (int i = this.listView.CheckedItems.Count - 1; i > -1; --i) 
{ 
    this.listView.CheckedItems[i].Remove(); 
} 
this.listView.EndUpdate(); 
+2

你真的需要一次加載25k項目嗎?如何通過滾動分頁或加載? –

+0

向我顯示代碼,我可以以毫秒爲單位刪除100個項目。只是檢查了代碼,我通過綁定來完成。 –

+0

用戶可以前後滾動並隨機查看列表部分,所以我不知道如何進行優化。 –

回答

0

ListView控件將觸發其從列表中刪除每一個項目的事件。您可以嘗試通過清除整個ListView然後再添加一個新的項目列表來避免這種情況,即刪除您想要刪除的100個項目。 這隻會觸發少數事件。

3

你可以從這裏開始你的優化:

List<int> toRemove = new List<int>(); 

foreach (ListViewItem item in this.listView.Items) 
{ 
    if (item.Checked) // check other remove conditions here 
     toRemove.Add(item.Index); 
} 

/* sort indices descending, so you'll remove items with higher indices first 
    and they will not be shifted when you remove items with lower indices */ 
toRemove.Sort((x, y) => y.CompareTo(x)); 
/* in this specific case you can simply use toRemove.Reverse(); 
    or iterate thru toRemove in reverse order 
    because it is already sorted ascending. 
    But you might want to force sort it descending in some other cases. 
*/ 

this.listView.BeginUpdate(); 

foreach (int itemIndex in toRemove) 
    this.listView.Items.RemoveAt(itemIndex); // use RemoveAt when possible. It's much faster with large collections 

this.listView.EndUpdate(); 
0

這是因爲每次你刪除的項目元素時,ListView控件必須找到該項目(walking the list to do so)和刷新CheckedItems集合(它迭代所有剩餘項目再次)所以複雜度是O^2。

最簡單的方法是緩存將selectedIndices和使用listItem.Items.RemoveAt():

var selectedIndices = listView.SelectedIndices.Cast<int>().Reverse().ToList(); 
listView.BeginUpdate(); 
foreach (var index in selectedIndices) { 
    listView.Items.RemoveAt(index); 
} 
listView.EndUpdate(); 

如果你不想使用Cast <>擴展方法,你可以用替換第一線:

List<int> oToDelete = new List<int>(SelectedIndices.Count); 
foreach (int iX in SelectedIndices) 
{ 
    oToDelete.Add(iX); 
} 
oToDelete.Reverse(); 
+0

謝謝,但listView似乎沒有RemoveAt方法。 –

+0

好吧,我發現它,它是內部項目,但演員崩潰。 –