C#Winforms如何在函数中更新toolStrip
我正在为一个程序构建一个UI,我不明白为什么在单击convert按钮后我的进度条不可见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问题,我不得不调用一个函数来更新空闲任务。有没有一
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();