在巨大的ListView上枚举ListView.SelectedIndices很慢

时间:2010-09-17 15:19:05

标签: c# .net winforms performance listview

我有一个带有VirtualMode = true和大量项目的ListView(现在约为800,000)。

我的目标是在每次更改所选项目时,对所有选定项目中的字段求和。

问题是,当选择大量项目时,枚举所有选定项目需要很长时间。例如,枚举800,000个选定项目需要1秒钟。这意味着对于每个单个选择更改,用户必须等待1秒才能再次响应GUI,这很烦人。

我无法理解为什么枚举所选项目的速度如此之慢,枚举一个简单数组中相同数量的项目什么都不会。

如何加快枚举ListView中所选项目的过程?

3 个答案:

答案 0 :(得分:1)

WinForms ListView的一个问题是它构建在Win32Control之上,因此每个对ListView的请求都必须从托管代码传递到无人代码并再返回。

var myArray = new int[myListView.SelectedIndices.Count];
myListView.SelectedIndices.CopyTo(myArray) 

可能会更快,值得尝试一下

否则您是否考虑过使用WPF?您可以为列表编写单个WPF控件,然后在WinForm表单中托管它。

答案 1 :(得分:0)

这取决于你是如何做的,你可能想用一些代码详细说明一下,但是当你选择每个项目时你不能保持一个运行总计,而不是每次选择时都通过整个列表是吗?

答案 2 :(得分:0)

潜在的控制是主要问题。只需要一定的时间来检查每个项目并确定它是否是下一个选定的行。

通过直接向控件发送消息,您可以使枚​​举过程快两倍:

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

private void button1_Click(object sender, EventArgs e)
{
    Stopwatch sw = new Stopwatch();

    sw.Start();
    IntPtr h = this.listView1.Handle;
    int j = 0;
    int i = SendMessage(h, 0x100C, -1, 2);
    while (i > -1) {
        j++;
        i = SendMessage(h, 0x100C, i, 2);
    }

    sw.Stop();
    this.toolStripStatusLabel1.Text = String.Format("Timed: {0} items in {1}ms",
        j, sw.ElapsedMilliseconds);
}

在我的机器上,这会减少迭代所选项目所需的时间。但这个过程永远不会是即时的。