2012-02-05 6 views
13

TListBoxなどのVCLコントロールでBeginUpdateとEndUpdateを使用すると、EndUpdateが呼び出されるまでコントロールが再描画されないように、Itemsでコントロールを読み込む処理が高速化されることがわかります。TStringListにBeginUpdateとEndUpdateがあるのはなぜですか?

例:

procedure TForm1.AddItems; 
var 
    i: Integer; 
begin 
    Screen.Cursor := crHourGlass; 
    try 
    ListBox1.Items.BeginUpdate; 
    try 
     for i := 0 to 5000 do 
     begin 
     ListBox1.Items.Add('Item' + IntToStr(i)); 
     end; 
    finally 
     ListBox1.Items.EndUpdate; 
    end; 
    finally 
    Screen.Cursor := crDefault; 
    end; 
end; 

procedure TForm1.AddItems; 
var 
    i: Integer; 
begin 
    Screen.Cursor := crHourGlass; 
    try 
    for i := 0 to 5000 do 
    begin 
     ListBox1.Items.Add('Item' + IntToStr(i)); 
    end; 
    finally 
    Screen.Cursor := crDefault; 
    end; 
end; 

リストボックスを再描画することが許可されているが、遅延はそうよう再描画防止することによって短絡させることができるため、上記の遅延を有することになります

今私はTStringListを使ってこれをテストしました:

procedure TForm1.AddItems; 
var 
    SL: TStringList; 
    i: Integer; 
begin 
    SL := TStringList.Create; 
    try 
    Screen.Cursor := crHourGlass; 
    try 
     SL.BeginUpdate; 
     try 
     for i := 0 to 5000 do 
     begin 
      SL.Add('Item' + IntToStr(i)); 
     end; 
     finally 
     SL.EndUpdate; 
     end; 

     ListBox1.Items.Assign(SL); 
    finally 
     Screen.Cursor := crDefault; 
    end; 
    finally 
    SL.Free; 
    end; 
end; 

TStringListのはメモリ内で実行していない視覚れるよう

が、彼らは本当にかかわらず、必要とされて... TStringListのはBegindUpdateとEndUpdateのを使用していますかどうかに関係なく、リストはほぼ同じ速度で移入されているようです。とにかく、TStringListでBeginUpdateとEndUpdateを使用する必要があります。これを行うのは良い方法ですか?

私はこれを聞いて馬鹿げているのですが、なぜTStringListにBeginUpdateとEndUpdateという手順がありますか?

あなたの意見を聞きたいと思っています。

感謝:)

答えて

21

BeginUpdateはSTRINGLISTのOnChangingOnChangeイベントを阻害します。接続されているものによっては、物事を大幅にスピードアップすることができます。

例では、BeginUpdate/EndUpdateは大きな違いはありません。 TStringlistインスタンスを使用してそれをリストビューに割り当てることは、かなり有効なアプローチです。

+0

+1また、OnChangeイベントを禁止します。 – RRUZ

+0

@RRUZ、確かに!ヒントをありがとう。 –

+0

ありがとう@UweRaabe私は知らないでしょう –

10

BeginUpdateおよびEndUpdateは、抽象基本クラスTStringsに導入されています。したがって、特に役に立ちませんが、TStringListはこの機能を継承します。しかし、他の多くの子孫にはもちろん有用です。

他の多くの子孫は私的な実装を持っています。たとえば、TListBoxに関連付けられたTStringsオブジェクトは、StdCtrlsユニットの実装セクションに対してはプライベートです。 TListBoxコントロールは項目リストをTStringsとして公開し、BeginUpdateEndUpdateを利用できるようにするには抽象基本クラスで宣言する必要があります。

私の見解では、あなたが知っているオブジェクトを使って作業するときは、これらのメソッドを無視しても問題ありません。TStringListです。

ここで、リストビューを作成するコードに関しては、中間点TStringListを使用している点は何もありません。リストビューに直接入力して、リストビューItemsBeginUpdate/EndUpdateを使用します。あなたのリストビューでまだ​​パフォーマンスの問題がある場合、ソリューションは仮想リストビューです。

+1

+1、TListBox.Items.Assignは内部的にAddとを呼び出す各エントリのTStrings.AddObjectを呼び出すので、TListBox.Items.Addを直接使用することは確かにわずかですPutObject。 –

+0

@Uweそれは、共通コントロールにデータを送信するのと比較して、まったく重要ではないでしょう。それがボトルネックになるだろう。リストビューの項目でBeginUpdateを実行すると、すべてのバリアントに同じ時間がかかります。 –

+1

しかし、TListBoxStrings.PutObjectは、SendMessageで実装されているListBox.SetItemDataを呼び出します。したがって、項目あたり2つのSendMessagesと比較して、1項目あたり1つのSendMessageです。 –

2

のロックパターンの実装は、hereです。

temporarily lockは、不要な通知を避けるために、クラスの側面になることができます。

あなたはDB.TDataSet.DisableControlsDB.TDataSet.EnableControlsに見つけることができると全く同じ。

関連する問題