TListViewでスムーズに項目を追加するには?

解決


まこと  2008-09-23 02:26:24  No: 32047

いつもお世話になってます m(__)m  また1点、質問をお願いします。

  ListView1 (TListView) に、1000個単位で項目を追加するときの処理なのですが、
現在、私は以下のようなコードで実現しています。

--------------------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
var
    ListItems: TListItems;
    Aitem: TListItem;
    i: Integer;
begin
  ListView1.Items.Clear;
  ListItems := TListItems.Create(ListView1);
  for i := 0 to 1000 do begin
    Aitem := ListItems.Add;
    Aitem.Caption := 'Caption1';
    Aitem.SubItems.Add('SubItem1');
    Aitem.SubItems.Add('SubItem2');
  end;
end;

--------------------------------------------------

ですが、このコードを実行すると、ListViewのスクロールバーなどが忙しく動いて
しまい、見栄えが悪くなってしまいます。

最初はBeginUpdate、EndUpdateを挟もうかと思ったのですが、できれば見えないと
ころで一括して処理をして、

TListBox.Assign(TStringList)

と同様に一括でデータを更新するような方式を考えたいのですが、どのように書けば
よいのでしょうか。

※  少し気になったのですが、上のコードでは、ListItems.Freeがないのですが、
このコードを何度も実行するとまずいでしょうか?今までは必要がなくなったコント
ロールに対しては即Freeを実行していたのですが、今回ばかりはFreeをかけると
ListView1に追加した項目が消えてしまうようなのですが。


ofZ  2008-09-23 07:12:15  No: 32048

ListView1.Items が TListItems だから、いちいちCreateする必要なし。

これで動いているのは、TListItems.Createの時点で、親のListViewを指定
しているためで、Addメソッドを使用すると、親に対してListItemを追加するから。

んで、自分でクリエイトしたTListItemsは、メモリーリークしている予感。

> ※  少し気になったのですが、上のコードでは、ListItems.Freeがないのですが、(略)
TListItemsのインスタンスは、親になったListViewをコントロールする。

for i := 0 to 1000 do begin
  ListItems := TListItems.Create(ListView1);
  Aitem := ListItems.Add;
  Aitem.Caption := 'Caption1';
end;

このような記述でも、ListViewには正常に追加されるだろうが、
1000個作成したListItemsのインスタンスのどれか一つでClearしたら、
全部消えます。

個人的にBeginUpdate、EndUpdateで囲んでしまうのがいいと思われる。
遅いのなら、進捗状況表示フォームでも作って、作成状況を表示したら?


まこと  2008-09-24 05:58:07  No: 32049

ご返答、どうもありがとうございます。ListItemsをCreateするべき利点
はないのですね。
  その後、いろいろ試行錯誤したのですが、結果的にBeginUpdateの方式で、
直接  ListView1.Items.Add  を使用することにしました。
  見た目にもなんとか満足できる程度の処理速度を確保して対応できました
ので、これで解決としたいと思います。どうもありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加