我遇到了一个非常奇怪的情况。这应该是如此简单,但我不确定为什么会这样。
我将一个选取框进度条设置为visible = false,因为它是初始状态。然后在运行期间的某个时刻,我调用我的一个函数,然后在调用它之前将PB设置为visible = true,在函数结束后,我将其设置为visible = false。它没有比这更简单。
If (something)
{
pb.visible=true;
runMyfunction(x, x, x, x,);
pb.visible=false;
}
问题是我从未见过PB。如果我注释掉我的函数并删除= false,则会显示PB,但只要我恢复了我的功能,PB就不会出现。
我尝试了各种方法。使用If语句确保我在触及函数之前得到一个进度条,它仍然保持PB隐藏。
我错过了什么吗?这似乎不应该是如此复杂。显示对象,运行函数,隐藏对象。对? :)
答案 0 :(得分:7)
这是因为你的功能正在占用UI线程。将ProgressBar设置为可见需要释放UI线程以绘制它,而是继续处理您的函数,从而没有时间绘制。
您可以通过调用以下方法解决此问题:Application.DoEvents
停止处理您的方法足够长的时间来处理一些Windows消息(并执行相关的绘图)。
Application.DoEvents
的一大问题是假设您正在从runMyfunction()
更新进度条,您将不得不经常致电Application.DoEvents
以允许您的PB进行抽奖,或者你会看到它,但你永远不会看到它更新。
更好的解决方案是将runMyfunction()
调用推送到后台线程,并从那里异步更新进度条。当然,这更复杂,但可以带来更好的用户体验。
答案 1 :(得分:7)
我的猜测是myRunFunction()
在UI线程上运行。
尝试在BackgroundWorker内运行并在调用RunWorkerAsync
之前启动ProgressBar并在RunWorkerCompleted
事件中停止。
使用代码示例编辑:
public class SomeClass
{
private BackgroundWorker _myFunctionBackgroundWorker;
private SomeProgressBar pb;
public SomeClass()
{
_myFunctionBackgroundWorker = new BackgroundWorker();
_myFunctionBackgroundWorker.DoWork += myFunctionBackgroundWorker_DoWork;
_myFunctionBackgroundWorker.RunWorkerCompleted += myFunctionBackgroundWorker_RunWorkerCompleted;
pb.visible = true;
_myFunctionBackgroundWorker.RunWorkerAsync();
}
private void myFunctionBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
runMyfunction();
}
private void myFunctionBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pb.visible = false;
}
}
答案 2 :(得分:2)
在runMyFunction()
方法调用Application.DoEvents()
内,强制您的应用重绘并处理Windows消息循环:
e.g。
void myRunFunction()
{
while (someFlag)
{
// do work
pb.Value = someValue;
Application.DoEvents();
}
}
答案 3 :(得分:1)
可能是您的功能正在运行并且完成得太快,您无法看到该栏。我知道我之前已经发生过几次。