2012-02-07 43 views
3

当我们的项目优化UI我ListView中发现真的很奇怪提升了,不明白它从何而来。的WinForms ListView和TreeView控件:奇怪的性能问题

简单增加5000元到ListView控件(查看:列表) - 3815毫秒:

for (int i = 0; i < 5000; i++) 
     listView1.Items.Add((Guid.NewGuid().ToString())); 

用的BeginUpdate()+ EndUpdate() - 2317毫秒:

listView1.BeginUpdate(); 
for (int i = 0; i < 5000; i++) 
    listView1.Items.Add((Guid.NewGuid().ToString())); 
listView1.EndUpdate(); 

带隐藏()+显示() - 163ms(无错,超过10倍):

listView1.Hide(); 
for (int i = 0; i < 5000; i++) 
    listView1.Items.Add((Guid.NewGuid().ToString())); 
listView1.Show(); 

风格也改变了。 而不是2列现在我有4.

为什么这种方式是如此之快? 此外,为什么从隐藏的ListView开始(可见:false),并在群体后显示它不具有相同的性能提升?

TreeView的是不同的。简单的添加5000个节点 - 2130毫秒:

for (int i = 0; i < 5000; i++) 
    treeView1.Nodes.Add((Guid.NewGuid().ToString())); 

带隐藏()+展() - 1048毫秒:

treeView1.Hide(); 
for (int i = 0; i < 5000; i++) 
    treeView1.Nodes.Add((Guid.NewGuid().ToString())); 
treeView1.Show(); 

用的BeginUpdate()+ EndUpdate() - 291毫秒:

treeView1.BeginUpdate(); 
for (int i = 0; i < 5000; i++) 
    treeView1.Nodes.Add((Guid.NewGuid().ToString())); 
treeView1.EndUpdate(); 
+1

将您的项目添加到列表中,然后调用'AddRange(...)'也应该手动指定您的列,而不是信任控件来动态分配它们。 – Seph 2012-02-07 10:55:24

回答

2

这似乎是一个错误。当控件被隐藏时,它不会计算这些项的范围(类似于Graphics.MeasureString或其本机等价物),当它们被添加时(这是有道理的),并且在稍后显示控件时(它是可能是一个错误)。出于这个原因,你得到4列而不是2.请注意,当你得到2列时,项目不会被截断,因为执行了这个大小计算。当您获得4列时,显示通常不正确。

为什么不从一开始就被无形做到吗?原因是,因为在这种情况下,直到您调用Show方法或创建强制创建句柄的任何内容,才会创建控件的句柄(底层Win32控件尚未创建)。然后,Show将首次创建句柄,并执行许多其他代码,包括OnHandleCreated,此时代码组织项目并计算其大小。

您可以检查IsHandleCreated属性为false,直到第一个Show呼叫,如果控制是从一开始就看不见。

您也可以明确地创建一个句柄,即。通过简单地尝试读取Handle属性(这会强制要创建的手柄),然后它的工作方式 - 是快,但显示是错误的:如果手柄前面创建

IntPtr handle = listView1.Handle; 
for (int i = 0; i < 5000; i++) 
    listView1.Items.Add((Guid.NewGuid().ToString())); 
listView1.Show(); 

中, OnHandleCreated以及大小计算也被调用,但在列表为空时。

0

如果您添加元素与隐藏列表视图..是元素后绘制元素,当您隐藏列表视图,比它将一次绘制所有元素..

+0

真正的问题是: 为什么从隐藏的ListView开始(可见:false),并在群体后显示它没有相同的性能提升? 为什么隐藏/显示更改可见列数? – Kuba 2012-02-07 10:36:36

+0

相同的答案..因为,如果它是可见的每一个元素,你正在添加的是绘制为单一的(每个新的元素 - 绘制后调用)..但如果你隐藏组件和后显示..它绘制在一个(添加所有元素,之后它全部使用gui).. – 2012-02-07 10:56:44