在我们的项目中优化用户界面时,我发现ListView中有很多奇怪的提升,并且不明白它来自哪里。
简单地向listView添加5000个元素(视图:列表) - 3815毫秒:
for (int i = 0; i < 5000; i++)
listView1.Items.Add((Guid.NewGuid().ToString()));
使用BeginUpdate()+ EndUpdate() - 2317 ms:
listView1.BeginUpdate();
for (int i = 0; i < 5000; i++)
listView1.Items.Add((Guid.NewGuid().ToString()));
listView1.EndUpdate();
使用Hide()+ Show() - 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()));
使用Hide()+ Show() - 1048 ms:
treeView1.Hide();
for (int i = 0; i < 5000; i++)
treeView1.Nodes.Add((Guid.NewGuid().ToString()));
treeView1.Show();
使用BeginUpdate()+ EndUpdate() - 291 ms:
treeView1.BeginUpdate();
for (int i = 0; i < 5000; i++)
treeView1.Nodes.Add((Guid.NewGuid().ToString()));
treeView1.EndUpdate();
答案 0 :(得分: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
以及大小计算,但当时列表为空。
答案 1 :(得分:0)
因为如果你在没有隐藏列表视图的情况下添加元素..在元素之后绘制元素,当你隐藏listview时,它会一次绘制所有元素..