 |
TListViewに、多数の項目を追加すると、表示に時間がかかってしまうことがあります。 そんなときはOwerDataプロパティを True にして、OnDataイベントで項目のCaptionなどを指定してやることで驚くほど高速な表示になります。 今回は普通に10000項目追加する場合と、OwnerData = True のときの処理時間を比較してみました。 |
 |
var
ST: TStringList; //項目文字列のの格納用
procedure TForm1.FormCreate(Sender: TObject);
begin
ST :=TStringList.Create;
ListView2.OwnerData :=True; //設計時に指定も可能
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
ST.Free;
end;
//普通に10000個のItemを追加
//10000個の解放にも処理時間がかかるためフォームを閉じてから
//IDEに処理が戻るまで時間がかかります。要注意
procedure TForm1.Button1Click(Sender: TObject);
var
i : Integer;
LI: TListItem;
t : Cardinal;
begin
ListView1.Clear;
t :=GetTickCount;
ListView1.Items.BeginUpdate;
for i := 1 to 10000 do
begin
LI := ListView1.Items.Add;
LI.Caption := inttostr(i);
end;
ListView1.Items.EndUpdate;
//私の環境では約4.5秒かかりました。
ShowMessage(IntToStr(GetTickCount -t));
end;
//OwnerData = True のバージョン
procedure TForm1.Button2Click(Sender: TObject);
var
i: integer;
t: Cardinal;
begin
t :=GetTickCount;
ST.Clear;
for i :=0 to 10000 do
ST.Add(InttoStr(i));
ListView2.Items.Count :=ST.Count;
//私の環境では約0.05秒ほどでした。
ShowMessage(IntToStr(GetTickCount -t));
end;
//OwnerData = Trueのときに必要な OnDataイベントの処理
procedure TForm1.ListView2Data(Sender: TObject; Item: TListItem);
begin
//項目ごと動的にデータを与える
Item.Caption :=ST[Item.Index];
end; |
TListを使って、TListItemの情報を格納していく方法もあります。 OnDataイベント内でSubItems.Addをするとメモリリークを起こすらしいですが、TList内の保持しているポインタをちゃんと解放してやれば(ClearList手続きがそれです)大丈夫そうです。MemCheackをやってみてもメモリリークは発生していませんでした。 |
var
vList: TList;
procedure TForm1.FormCreate(Sender: TObject);
begin
vList := TList.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
ClearList(vList);
vList.Free;
end;
//一旦リストの中のTListItemを解放するヘルパー手続き
procedure TForm1.ClearList(List: TList);
var
i :integer;
begin
for i := vList.Count -1 downto 0 do
begin
TListItem(vList[i]).Free;
vList.Delete(i);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i : Integer;
LI : TListItem;
begin
ListView1.Items.BeginUpdate;
ClearList(vList);
for i := 1 to 10000 do
begin
LI := TListItem.Create(ListView1.Items);
LI.Caption := InttoStr(i);
LI.SubItems.Add(InttoStr(i * 2));
vList.Add(LI);
end;
ListView1.Items.Count := vList.Count;
ListView1.Items.EndUpdate;
end;
//TListのポインタをTListItemにキャストして使用
procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
Item.Caption := TListItem(vList[Item.Index]).Caption;
Item.SubItems.Add(TListItem(vList[Item.Index]).SubItems[0]);
end; |
 |
|
|
   |