2017-05-06 2 views
0

これはC# - WinFormに関する質問です。 私はlistBoxで検索しようとしています。リストボックスにはいくつかのアイテムがあります。プログラムのロード時に、listBox内のすべての項目が、 'tempList'というタイプの文字列のリストにコピーされます。 TextBoxもあります。ユーザーがTextBoxの入力を開始すると、listBoxはClear()メソッドを使用してクリアされます。その後、テキストボックス内の単語は、foreachブロックを使用してtempList内で検索されます。すべての一致がlistBoxに追加され、ユーザーに表示されます。 私はこのコードを思い付いた:listBoxでbackgroundWorkerを使って検索する

private void textBox1_TextChanged(object sender, EventArgs e) 
    { 
     listBox1.Items.Clear(); 
     foreach (string item in tempList) 
     { 
      if (item.ToLower().Contains(textBox1.Text.ToLower())) 
      { 
       listBox1.Items.Add(item); 
      } 
     } 
    } 

問題は、ユーザーが最初の文字で、テキストボックスに入力し始めると、UIが破断し、ユーザーがそのために検索されるまで待たなければならないこと、です1文字が終了した後、再度入力することができ、これはすべての文字で発生します。これを解決するために、私はbackgroundWorkerを使うことができると考えました。しかし、私はこのシナリオのためにそれを使用する方法を理解していません。役に立ったことは何でも感謝します。

+0

異なるインターフェイスでオートコンプリート機能を複製しようとしているようです。なぜ、既に組み込まれているUI機能を使用しないのですか? – Steve

+0

私はオートコンプリートが、ユーザーが入力してテキストボックスの内容に追加する際に単語を示唆していると思いますか?それは私の意図ではありません。私は特に、テキストボックスに入力された単語をlistBoxで検索しようとしています。 – arm

+0

ユーザーがテキストボックスを離れるか、または「Enter」を押した後で検索を開始する必要があります。 – Fabio

答えて

0

... ...

BackgroundWorker listSearch = new BackgroundWorker(); 

が...

 listSearch.DoWork += ListSearch_DoWork; 
     listSearch.RunWorkerCompleted += ListSearch_RunWorkerCompleted; 

イベントハンドラの実装を初期化...

private void textBox1_TextChanged(object sender, EventArgs e) 
    { 
     listSearch.RunWorkerAsync(textBox1.Text); 
    } 

    private void ListSearch_DoWork(object sender, DoWorkEventArgs e) 
    { 
     string text = e.Argument as string; 
     List<string> items = new List<string>(); 
     foreach (string item in tempList) 
     { 
      if (item.ToLower().Contains(text.ToLower())) 
      { 
       items.Add(item); 
      } 
     } 
     e.Result = items.ToArray(); 
    } 

    private void ListSearch_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     string[] items = e.Result as string[]; 
     Invoke((Action)(() => 
     { 
      listBox1.Items.Clear(); 
      foreach(string item in items) 
      { 
       listBox1.Items.Add(item); 
      } 
     })); 
    } 
+0

すごい!それはまさに私が望むものに似ています。十分にあなたに感謝することはできません。 – arm

+0

注:実行ワーカー完了ハンドラ内の呼び出しは不必要です。私はちょうど迅速なチェックを行い、完了した実行ワーカーは常にバックグラウンドワーカーが作成された同じスレッド上で実行されます。だから、少し単純化することができます。 – AQuirky

0

宣言をBackgroundWorkerのクラスを使用しますの使用クラスはBackgroundWorkerよりずっと簡単です。コードを簡単にするために結合

private async void TextBox_TextChanged(object sender, EventArgs e) 
{ 
    listBox.DataSource = null; 

    var task = Task.Run(() => 
     { 
      var resultList = new List<string>(); 

      foreach (string item in tempList) 
       if (item.ToLower().Contains(textBox.Text.ToLower())) 
        resultList.Add(item); 

      return resultList; 
     }); 

    listBox.DataSource = await task; 
} 

使用データ:

は、このシンプルなソリューションをお試しください。プログラムの読み込み時に

listBox.DataSource = tempList; 
関連する問題