如何加速Winforms ListView项目删除?

时间:2012-10-11 03:57:42

标签: c# .net winforms performance listview

我已经使用了listView.BeginUpdate()listView.EndUpdate(),但是当我删除25k中的100个项目时,它仍然需要10秒钟。

任何让它更快的想法和技巧?

编辑:

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

3 个答案:

答案 0 :(得分: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();

答案 1 :(得分:0)

ListView将触发从列表中删除的每个项目的事件。您可以尝试通过清除整个ListView然后立即添加新的项目列表来避免这种情况,这些项目将被删除您要删除的100个项目。 这只会引发一些事件。

答案 2 :(得分:0)

那是因为每次从Items中删除元素时,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&lt;&gt;扩展方法,你可以用第一行代替:

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