在delphi中有一个包含几个字段的列表视图。线程检查项目并将其添加到listview。如果有相同的标题,则会在此标题的子项中添加一个整数。当项目数小于2000时,性能良好。当检查和添加项目和项目计数超过约2000时,性能很差。当项目数量大于20,000时,性能可以描述为非常慢。当项目可能达到50,000或100,000时,有没有办法在listview中快速读写?
非常感谢您提前
编辑:
我们已经阅读了您的所有答案,并感谢您的帮助。
答案 0 :(得分:11)
Delphi TListView控件是Windows列表视图组件的包装器。在默认操作模式下,列表数据的副本将从您的应用程序传输到Windows控件,这很慢。
此替代方案称为Windows术语中的虚拟列表视图。您的应用程序未将数据传递给Windows控件。相反,当控件需要显示数据时,它会向您的应用询问所需的数据。
Delphi TListView控件使用OwnerData属性公开虚拟列表视图。你必须稍微重新编写列表视图代码,但它确实是唯一的解决方案。
答案 1 :(得分:9)
您只需在“虚拟”模式下使用列表即可。
与此代码一样(替换为数据库中的某些数据或TStringList等):
procedure TForm1.ListBox1Data(Control: TWinControl; Index: Integer;
var Data: String);
begin
Data := Format('Item %d',[Index+1]); // set the text to be displayed
end;
您可以使用lbVirtualOwnerDraw样式进一步自定义绘图,并且必须使用OnDrawItem事件处理程序绘制项目。 Delphi文档中有一些示例代码(至少在Delphi 7下)。 ;)
在虚拟模式下,您可以即时显示50000或100000个项目。
对于存储文本,使用旧的TStringList将比TListBox的Items方法更快,因为这个Items []属性必须与Windows通信,每个项目的“慢”GDI消息,而TStringList将只需将文本存储在Delphi堆中,这通常要快得多。
答案 2 :(得分:6)
您可以在listview上调用BeginUpdate和EndUpdate来提高性能,方法是阻止listview在更新时重绘自身。但这可能不会给你你想要的提升。 此外,您需要知道直接从线程访问VCL控件是不安全的,除非已同步。
我认为最好跳过列表视图并选择像Virtual Tree View这样既优质又免费的第三方控件。 :)
答案 3 :(得分:3)
几年前,我们发现除了BeginUpdate / EndUpdate之外,在向其添加大量数据之前将ListView的ViewStyle更改为vsiscon,并在我们完成大幅提升的性能之后返回到vsRepord。如果我没记错的话,那就是在Windows 98和Windows 2000上,所以我不确定是否仍然如此。
答案 4 :(得分:3)
更新项目时,必须使用BeginUpdate和EndUpdate。 根据您的描述,这听起来像是在循环查找特定标题的项目。这很慢,显然会有更大量的数据。
由于您要查找匹配的标题,请使用listviews FindCaption 功能。
这是一个Windows调用来搜索项目,并且相当快速和简单。如果它找到它它会传回该项目,您可以引用它来更新子项目。否则,请创建一个新项目并继续处理。
只要您的线程安全且您应该能够看到不错的性能。
HTH。
答案 5 :(得分:2)
使用OnData处理程序尝试虚拟Listview。
数据保留在您自己的数据结构中,listview调用您的OnData处理程序,以便在需要时只获取所需的数据项。即,在您提出要求时,您可以从数据结构中提取特定数据。
您的另一项工作是将listview的ItemCount保留为列表中的项目数。