如何在delphi中快速读取和编写listview?

时间:2010-11-20 12:07:26

标签: delphi

在delphi中有一个包含几个字段的列表视图。线程检查项目并将其添加到listview。如果有相同的标题,则会在此标题的子项中添加一个整数。当项目数小于2000时,性能良好。当检查和添加项目和项目计数超过约2000时,性能很差。当项目数量大于20,000时,性能可以描述为非常慢。当项目可能达到50,000或100,000时,有没有办法在listview中快速读写?

非常感谢您提前

编辑:

我们已经阅读了您的所有答案,并感谢您的帮助。

6 个答案:

答案 0 :(得分:11)

Delphi TListView控件是Windows列表视图组件的包装器。在默认操作模式下,列表数据的副本将从您的应用程序传输到Windows控件,这很慢。

此替代方案称为Windows术语中的虚拟列表视图。您的应用程序未将数据传递给Windows控件。相反,当控件需要显示数据时,它会向您的应用询问所需的数据。

Delphi TListView控件使用OwnerData属性公开虚拟列表视图。你必须稍微重新编写列表视图代码,但它确实是唯一的解决方案。

答案 1 :(得分:9)

您只需在“虚拟”模式下使用列表即可。

  1. 在表单上放置TListBox;
  2. 将Style属性设置为lbVirtual。
  3. 将Count属性设置为列表中的项目数。
  4. 然后使用OnData处理程序提供要求显示的文本:
  5. 与此代码一样(替换为数据库中的某些数据或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保留为列表中的项目数。