2009-07-22 10 views
1

DelphiのTMemo.Add()メソッドの動作をスムーズにスクロールするリストボックスを取得しようとしています。.Add呼び出し中にListBoxの表示を更新する方法

以下のテストコードを使用してしばらくスクロールしてから約600で一時停止し、完了するまでリフレッシュに失敗します。

私は、以下のコードを別のスレッドで実行して、成功するように更新する必要があることを参照しています。これは私が定期的に使っているものです。私はもっと簡単な解決策を望んでいます。

 for (int i = 0; i < 10000; i++) 
     { 
      listBox1.Items.Add(i); 
      listBox1.SetSelected(listBox1.Items.Count - 1, true); 
      listBox1.SelectedIndex = -1; 
      this.Refresh(); // overkill but just to make sure... 
     } 
+1

スタックオーバーフローへようこそ;) –

答えて

2

私はやってお勧めしませんその継続的な再描画のパフォーマンスコストは本当にあなたが約600で見ているものであるスピードを殺すよう - それはちょうどそれが処理するにはあまりにも多くなってきました。

ループ中にApplication.Refreshを呼び出して、ウィンドウメッセージを処理し続けることができます。ウィンドウメッセージは応答を維持しますが、パフォーマンスを低下させます。

最近見た戦略は単純ではありませんが、効果的です。リストボックスを偽造することです。したがって、追加中にリストボックスを非表示にして、それをリストボックスのようなものに描画するために使用するパネルなどで置き換えます。やり遂げられたら元に戻す。このようにして、非常にスムーズになり、視覚的に魅力的な効果が得られます。より多くの仕事が、それに値するかもしれません。

0

私はこのようなループでapplication.refreshを使用していませんが(完全にうまくいくかもしれませんが)、application.processMessagesを試してみてください。私はそれを使用して、それは私のために動作します。 -don

0

これについては、別の方法で考えるとよいでしょう。私は、あなたが進行中であることをユーザーに示す項目を追加するたびに、リストボックスを再描画することを前提としています。このような場合は、その後、私は似たような状況で使用するアプローチがあるに:制御

  • 追加する
  • は、UIスレッドへのコールバックを作成し、別のスレッドで作業を行う上

    1. コールBeginUpdateメソッド進行状況バーを更新します。作業が不定期である場合は、ステップ1のマーキーモードでプログレスバーを実行してください。
    2. 終了したら、UIスレッドをコールバックして作業が完了したことを示し、EndUpdateを呼び出す必要があります。
  • 0

    私のコンピュータでは、フォームとやりとりするまでは正常に動作しますが、その時点では更新が中止されます。しかし、それはポイントではありません。実際の質問は、10000項目のリストボックスを塗りつぶし、表示されるすべての項目に対して更新する必要がある理由は何ですか?

    一つの合理的な選択肢は、(おそらく別のスレッドで)アイテムまでバッチになり、その後、すべての今して表示するためのアイテムの数を投稿することができます:

    private void SomeMethod() 
    { 
        ThreadPool.QueueUserWorkItem((state) => 
         { 
          List<int> ints = new List<int>(); 
          for (int i = 0; i < 10000; i++) 
          { 
           ints.Add(i); 
           if (i % 25 == 0) // update the listbox on every 25th item 
           { 
            this.Invoke(
              new Action<IEnumerable<int>>(AddItemsToList), ints); 
            ints.Clear(); 
           } 
           if (ints.Count != 0) // make sure to add any "trailing" items 
           { 
            this.Invoke(
              new Action<IEnumerable<int>>(AddItemsToList), ints); 
           } 
          } 
         }); 
    } 
    
    private void AddItemsToList(IEnumerable<int> items) 
    { 
        listBox1.BeginUpdate(); 
        foreach (var item in items) 
        { 
         listBox1.Items.Add(item); 
        } 
        listBox1.EndUpdate(); 
        listBox1.SetSelected(listBox1.Items.Count - 1, true); 
        listBox1.SelectedIndex = -1; 
        listBox1.Update(); 
    } 
    

    そして今、あなたもかなり応答UIを持っていますリストが読み込まれている間。

    関連する問題