2

Windowsフォームには、リモートデータベースを検索していくつかの結果を表示するイベントを発生させる検索ボックスがあります。クエリは非常に高速で、通常はほんの一瞬ですが、遅延が目立つ場合は、フォームのステータスバーに進行状況バーとラベルがあります。ユーザーが[検索]をクリックすると、ステータスラベルが表示され、進行状況バーに進行状況が表示されます。次に、結果が返されると、ラベルが消え、進行状況バーがいっぱいになります。かなり基本的な応答。

問題は、これらのアクションをこの順序で実行させることができないことです。以下のコードを使用して、[検索]をクリックします。結果が表示されるまで何も起こりません。その後、進行状況バーが0から100までいっぱいになります。ラベルは表示されません。イベントの直後にsleepコマンドをスローして、それを見逃していないことを確認しましたが、最初の2つのステートメントが実行されていないかのようです。私はここで何が間違っているのですか?

 private void searchButton_Click(object sender, EventArgs e)
    {
        toolStripStatusLabel1.Visible = true;
        toolStripProgressBar1.Value = 20;
        m_changeRequestedEvents.Fire<String>("SearchTerm", searchTextBox.Text);
        toolStripProgressBar1.Value = 100;
        toolStripStatusLabel1.Visible = false;
    }
4

1 に答える 1

2

提供されたコードはUI属性を変更しますが、searchButton_Clickが戻るまで、スレッドはUIを再描画できません。したがって、イベントの前に行われた変更は適用されません。これは、イベントの前に行われた変更が、メソッドが戻るときに適用される変更によって上書きされるためです。

代わりに、イベントを発生させる前にUI属性を更新してください。

searchButton.Enabled = false;
toolStripProgressBar1.Value = 0;
toolStripStatusLabel1.Visible = true;
m_changeRequestedEvents.Fire<String>("SearchTerm", searchTextBox.Text);

また、イベントハンドラーから、別のスレッド(BackgroundWorker)でクエリを実行して、その間にUIを更新できるようにします。

private void View_OnSearchTermChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
{
    m_search_bgw = new BackgroundWorker();
    ...
    m_DBHandler.current_worker = m_search_bgw;
    m_search_bgw.RunWorkerAsync(args.RequestedValue);
}

次に、BackgroundWorkerスレッドが完了したときに呼び出されるメソッドでUIを再度更新します。

void UpdateView(DataView projects)
{
    dataGridView1.DataSource = projects;
    ...
    toolStripProgressBar1.Value = 100;
    toolStripStatusLabel1.Visible = false;
}
于 2010-10-16T22:38:08.123 に答える