C# 与操作一起更新ToolStripProgressBar和ToolStripStatusLabel

C# 与操作一起更新ToolStripProgressBar和ToolStripStatusLabel,c#,winforms,events,progress-bar,statusbar,C#,Winforms,Events,Progress Bar,Statusbar,在Windows窗体中,我有一个搜索框,它触发一个事件来搜索远程数据库并显示一些结果。查询速度非常快,通常只有几分之一秒,但如果延迟很明显,表单的状态栏中会有一个进度条和标签。当用户单击“搜索”时,状态标签应出现,进度条显示一些进度。然后当结果返回时,标签应该消失,进度条应该满了。相当基本的反应 问题是,我不能让这些行动按那个顺序发生。使用下面的代码,我单击“搜索”,在显示结果之前不会发生任何事情,然后进度条从0填充到100。标签从未出现过。我甚至在事件发生后立即输入了一个sleep命令,以确保

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

问题是,我不能让这些行动按那个顺序发生。使用下面的代码,我单击“搜索”,在显示结果之前不会发生任何事情,然后进度条从0填充到100。标签从未出现过。我甚至在事件发生后立即输入了一个sleep命令,以确保我不仅没有错过它,而且好像前两条语句没有被执行。我做错了什么

 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;
    }
private void searchButton\u单击(对象发送者,事件参数e)
{
toolStripStatusLabel1.Visible=true;
toolStripProgressBar1.Value=20;
m_changeRequestedEvents.Fire(“SearchTerm”,searchTextBox.Text);
toolStripProgressBar1.值=100;
toolStripStatusLabel1.Visible=false;
}

提供的代码会更改UI属性,但在searchButton\u单击返回之前,线程无法重新绘制UI。因此,事件之前所做的更改永远不会应用,因为它们会被事件之后所做的更改覆盖,然后在方法返回时应用这些更改

而是在触发事件之前更新UI属性:

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

这个Fire方法是否启动另一个线程来执行数据库查询?如果不是,你从来没有看到标签的原因是你在同一条线上做每件事。在Windows窗体中,主线程仅负责绘制窗口和内容。如果它在执行ADO.NET内容时被挂起,那么它就不能很好地绕过重新绘制标签的问题。当它返回到服务控件的布局/绘制事件时,它将已经完成查询并将其设置回不可见。不,这是一个单线程应用程序。该事件从另一个类运行DB查询,然后该类向UI触发另一个事件以更新结果表。我知道它在运行查询时无法重新绘制,但鉴于上面的代码,我认为它会在执行后端操作之前部分填充栏并显示标签,然后在完成后执行最后2行。在searchButton_Click()完成之前,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);
}
void UpdateView(DataView projects)
{
    dataGridView1.DataSource = projects;
    ...
    toolStripProgressBar1.Value = 100;
    toolStripStatusLabel1.Visible = false;
}