C#Winforms如何在函数中更新toolStrip

C#Winforms如何在函数中更新toolStrip,c#,winforms,visible,toolstrip,C#,Winforms,Visible,Toolstrip,我正在为一个程序构建一个UI,我不明白为什么在单击convert按钮后我的进度条不可见 private void convertButton_Click(object sender, EventArgs e) { toolStripProgressBar.Visible = true; ... toolStripProgressBar.Visible = false; } 我在Python中遇到了类似的tkinter问题,我不得不调用一个函数来更新空闲任务。有没有一

我正在为一个程序构建一个UI,我不明白为什么在单击convert按钮后我的进度条不可见

private void convertButton_Click(object sender, EventArgs e)
{
    toolStripProgressBar.Visible = true;

    ...

    toolStripProgressBar.Visible = false;
}
我在Python中遇到了类似的tkinter问题,我不得不调用一个函数来更新空闲任务。有没有一种方法可以在不使用线程的情况下对windows窗体执行此操作

编辑:在旁注中,这是toolStrip中的进度条,其中还包含一个标签,该标签使用状态栏文本进行更新。有没有办法把标签放在左边,把进度条放在另一边,而不是把它放在左边的旁边?

好吧,有一种方法可以不用线程(
Application.DoEvents
)来实现这一点,但我强烈建议您不要使用它。重入是令人讨厌的,你真的不想让UI线程被束缚住

改为使用-它很简单,而且它几乎是为进度条设计的。它省去了使用单独线程并向UI线程报告进度的麻烦。不需要
控件。调用
等-它会为您解决这一问题

有-你不需要花太长时间就可以开始使用它。

好吧,有一种方法可以不用线程(
Application.DoEvents
)来实现这一点,但我强烈建议你不要使用它。重入是令人讨厌的,你真的不想让UI线程被束缚住

改为使用-它很简单,而且它几乎是为进度条设计的。它省去了使用单独线程并向UI线程报告进度的麻烦。不需要
控件。调用
等-它会为您解决这一问题


有-你不需要花太长时间就可以开始使用它。

根据你提出的问题,没有线程就可以做到这一点,即使用Application.DoEvents();。(只需在将进度条设置为可见后立即添加该调用。)


现在我同意Jon Skeet的观点,尽管BackgroundWorker是一种更好的方法,但它确实使用了一个单独的线程。

根据您提出的没有线程的方法,即使用Application.DoEvents();。(只需在将进度条设置为可见后立即添加该调用。)


现在我同意Jon Skeet的观点,尽管BackgroundWorker是一种更好的方法,但它确实使用了一个单独的线程。

您需要在一个与UI线程分离的线程中执行流程,然后让它定期向UI线程报告其进度。如果转换操作在UI线程内工作,则在操作完成之前,转换操作将一直没有响应。

您需要在与UI线程分离的线程中执行流程,然后让它定期向UI线程报告其进度。如果您的转换操作在UI线程内工作,它将在操作完成之前完全没有响应。

我猜问题在于代码中的
“…”
是一个长期运行的过程。UI更新不是即时的,但必须在windows中通过消息队列运行,然后绘制到屏幕上。队列被抽运,绘制与事件发生在同一线程中

因此,任何长时间运行的任务都需要移动到不同的线程。除此之外,您的代码行需要在该线程终止后调用。否则,请设置进度条,然后立即再次将其关闭


一种方法是使用BackgroundWorker控件。

我猜问题在于代码中的
“…”
是一个长期运行的过程。UI更新不是即时的,但必须在windows中通过消息队列运行,然后绘制到屏幕上。队列被抽运,绘制与事件发生在同一线程中

因此,任何长时间运行的任务都需要移动到不同的线程。除此之外,您的代码行需要在该线程终止后调用。否则,请设置进度条,然后立即再次将其关闭


一种方法是使用BackgroundWorker控件。

只有在允许绘制消息处理过程中出现的进度条时,进度条才可见。消息处理通常不能发生在事件处理程序的中间。如果希望进度条显示,则必须将Visiblity设置为true,启动后台线程以完成工作并从处理程序返回

只有允许在处理消息期间绘制进度条时,进度条才可见。消息处理通常不能发生在事件处理程序的中间。如果希望进度条显示,则必须将Visiblity设置为true,启动后台线程以完成工作并从处理程序返回

这里有两个链接试图解释事情是如何运作的:

现在,我将尽可能快地解释它。windows窗体应用程序中发生的大多数事情都发生在单个线程中,通常是同一个线程Main()在其中运行。如果打开Program.cs,您将看到Main()有一行,如下所示:

Application.Run(new Form1());
如果您随时调试应用程序并检查调用堆栈,您将看到它将追溯到该Run方法。这意味着Windows窗体应用程序实际上是run方法的连续运行。那么,Run在做什么?Run正在吞噬一个消息队列,Windows通过该队列向其发送消息。Run然后将这些消息发送到正确的控件,这些控件本身会执行一些操作,如添加与按下的键对应的文本、重新绘制自身等。请注意,所有这些都是在循环过程中发生的,循环沿着单个线程运行,所以无论您是在键入还是只是移动窗口,这些消息的负载被传递到应用程序上,而应用程序又在处理它们
toolStripStatusBar1.PerformStep();
statusStrip1.Refresh();