ListView拥有灵活易用的特点,它是Windows的标准控件。做过数据库的朋友都知道,ListView在插入大量的数据时会很慢很慢(如果你是用*DBGrid,那就算了:)。通过测试,即使是使用oracle10g,列出10w条数据也要几十秒(也可能是我机子太慢了),而且还占用很大的内存。参照msdn里面的内容,说简单点是这样的:因为ListView插入一条Item时,它会同时插入Item所对应的数据,也就是说ListView中的Item拥有一块数据区,这数据区用来保存Item的信息(标题、字体等等)。所以Item一多,初始化这些数据区就很慢了。
而Virtual List不一样,ListView中每一条Item不会拥有自己的数据,当要显示数据时,它会发送消息问父窗体索要显示的内容。所以在父窗体接受相应的消息,再配合数据库记录的移动,就可以实现数据库结合Virtual List的功能了。
具体实现方法如下(Delphi7和Delphi2006都封装了Virtual List,老Delphi没试过):
首先,在窗体上添加一个控件:TListview(Win32页)、不用改名。
添加如下代码:
procedure TForm1.FormCreate( Sender: TObject );
begin
with ListView1 do
begin
ViewStyle := vsReport;
OwnerData := True;
Items.Count := 10000; // 注意:在此处必须主动的设置Virtual List的行数
with Columns.Add do
Caption := ’行号’;
end;
end;
// ListView的OnData事件
procedure TForm1.ListView1Data( Sender: TObject; Item: TListItem );
begin
Item.Caption := IntToStr( Item.Index );
end;
大家可以看到,OnData事件用来接收Virtual List传过来的需要显示的Item,大家可以在这个事件里对Item的相关信息进行显示。
注意:由于Virtual List的Item不保存任何数据,所以在OnData事件中经过显示后的Item仍然不具有任何数据。因此,即使遍历完所有Item的显示,还会不停的激发OnData事件,Virtual List的Item需要你给它数据进行显示,而不是给它数据进行保存。
正因为Virtual List有这个特性,所以我们可以很好的利用这个特性和数据库结合。因为我们用数据库保存数据,而用Virtual List把它显示出来。我们可以通过OnData事件中Item的索引值(Item.Index)来移动ado记录集指针(Recordset.Move)到这个指针,然后获取当前记录集上的数据显示出来就可以了。
只要改上面的两个地方:
Items.Count := Recordset.RecordCount; // 获取记录集的行数
在OnData里面:
Items.Caption := Recordset.Fields[ Item.Index ].Value;
……
相信大家都知道原理了,那么动手做吧:)
在压缩包里带了两个代码,一个是简单的Virtual List演示,另外一个是Virtual List结合ado列出数据的演示。
大家可以在msdn上通过索引“VListVw: Virtual ListView Control Sample”,可以了解一下VirtualList的sdk例子。
unit untMain;
interface
uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
ADODB_TLB,
ComCtrls,
StdCtrls,
TVLUtils;
type
TfrmMain = class( TForm )
lvwMain: TListView;
btnStart: TButton;
procedure FormCreate( Sender: TObject );
procedure btnStartClick( Sender: TObject );
procedure lvwMainData( Sender: TObject; Item: TListItem );
procedure FormDestroy( Sender: TObject );
责任编辑:小草