更新ToolStripProgressBar和ToolStripStatusLabel以及操作

时间:2010-06-15 21:04:41

标签: c# winforms events progress-bar statusbar

在Windows窗体中,我有一个搜索框,可以触发事件来搜索远程数据库并显示一些结果。查询非常快,通常只有几分之一秒,但如果延迟明显,则表单的状态栏中会有一个进度条和标签。当用户单击“搜索”时,应显示状态标签,进度条显示一些进度。然后当结果返回时,标签应该消失,进度条应该已满。非常基本的回应。

问题是,我无法按顺序执行这些操作。使用下面的代码,我点击“搜索”,在显示结果之前没有任何反应,然后进度条从0到100填满。标签永远不会出现。我甚至在事件发生后立即投入了一个睡眠命令,以确保我不会错过它,但就好像前两个语句没有被执行一样。我在这里做错了什么?

 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;
    }

1 个答案:

答案 0 :(得分:1)

提供的代码更改了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;
}