我有一个像这样的窗体:1)单击按钮将执行需要很长时间才能完成的操作,2)显示进度有多大百分比的标签。
在我提到的漫长操作中,我编写代码来更新标签的Text属性,但它不起作用!
请帮我正确显示进度状态。
答案 0 :(得分:4)
您可以查看BackgroundWorker
课程(请参阅MSDN overview)。它允许您在后台运行一些长时间运行的操作,并将后台更新(百分比)和完成从后台任务报告给用户界面。请注意,您需要自己计算进度百分比。
但是,BackgroundWorker
类负责其他棘手的方面,例如将进度报告发送到主GUI线程(您可以安全地更新用户界面)。
答案 1 :(得分:2)
您希望创建一个执行任务的工作线程,并偶尔将其更新报告给表单线程。如果您在UI线程中完成所有工作,您的UI将被锁定,并且不会正确更新进度/标签。
在启动工作线程之前,计算您认为该过程将采取的步骤总数。启动工作线程。在每个工作单元之后,您在UI线程上调用更新方法以增加该过程。
您需要查看BackgroundWorker类。
如果您的应用程序中有几个,我建议创建一个过程接口(例如IProgressProcess)。此接口将包含用于执行进程和报告更新的方法。您将通过此接口实现来创建所有流程类。编写包含进度条的控件,并通过构造函数或属性接受IProgressProcess。然后,它可以使用您的自定义流程执行并沿着进度条移动。然后,您可以让自定义进度控件在过程完成或取消时发送事件。
答案 2 :(得分:1)
如果您尝试在发生操作的同一线程上更新UI,通常会发生这种情况。您可以通过几种不同的方式来实现这一目标。
答案 3 :(得分:1)
您没有看到任何更改的原因是更改导致消息重绘标签,但主线程正在忙于工作,因此它不响应消息。
最简单的解决方案是在更新标签后调用Application.DoEvents
。这可以快速解决您的问题,但它仍然会使应用程序无法以任何其他方式响应。
好的解决方案是在单独的线程中启动操作。这样,您的主线程可以在操作运行时自由处理消息。但是,在单独的线程中工作意味着在与UI通信时更多的工作。如果要更新控件,则必须使用Invoke方法启动在主线程中运行的方法,以便它可以访问控件。或者,您可以只更新线程中的变量,并使用定时器控件定期检查变量中的更改并相应地更新标签。