我无法找到其他人遇到同样的问题,所以希望有人可能会有一些想法或者能够指出我另一个答案。
当按下表单上的按钮运行某个功能时,另一个按钮应该可见。但是,按钮永远不会显示,即使它是函数中的第一件事。该函数中的所有其他代码都可以正常运行。
以下是代码:
private void trackbar_Change(object sender, EventArgs e)
{
button.Visible = true;
progressbar.Visible = true;
...
progressbar.Visible = false;
button.Visible = false;
}
进度条显示并且工作正常,函数中的所有其他代码也可以正常工作,但按钮永远不会显示。
如果我从函数末尾删除button.Visible = false;
,则按钮显示,但仅在所有其他代码执行完毕后显示。像这样:
private void trackbar_Change(object sender, EventArgs e)
{
button.Visible = true;
progressbar.Visible = true;
...
progressbar.Visible = false;
//button.Visible = false;
}
注释掉该行会导致按钮显示。现在如果我在按钮行后面添加一个消息框,那么它也可以工作。
private void trackbar_Change(object sender, EventArgs e)
{
button.Visible = true;
MessageBox.Show("Button should be visible now");
progressbar.Visible = true;
...
progressbar.Visible = false;
button.Visible = false;
}
在按钮行后添加消息框导致按钮在正确的时间显示。
有没有人有任何想法为什么这个按钮的表现如此?
答案 0 :(得分:8)
听起来GUI线程很忙。尝试通过调用Application.DoEvents()强制屏幕更新,例如:
button.Visible = true;
progressbar.Visible = true;
Application.DoEvents();
DoEvents()
将强制处理消息队列中的所有消息。
更好的解决方案将移动主UI线程的长时间运行的线程。使用BackgroundWorker执行任务。
它将使整个表单更具响应性。例如,您可以与表单进行交互,但它不会变成“白色”。实现BackgroundWorker很简单,对于主UI线程上的长时间运行进程是必须的,
答案 1 :(得分:1)
问题是你在UI线程上执行一个长时间运行的进程,因此在线程空闲之前不会将按钮设置为可见。但是,在线程空闲时,您将可见设置为false。
执行此操作的最佳方法是在后台工作程序上执行长时间运行的进程,以便不阻止UI线程。进度条工作的原因是因为它在不同的线程上运行。
还有另外一种方法 - 但可能不那么正确 - 这是在将visible设置为true后在表单上发出Refresh。
如果您需要有关BackgroundWorker的帮助,请告诉我,但它非常直接。
答案 2 :(得分:0)
运行Windows窗体时,它会创建新窗体,然后等待事件处理。每次表单处理事件时,它都会处理与该事件相关的所有代码。所有其他事件在队列中等待。当您的代码处理事件时,您的应用程序不会响应。例如,如果在顶部拖动另一个窗口,窗口不会重新绘制。
如果在代码中调用DoEvents,则应用程序可以处理其他事件。
使用Application.DoEvents();
答案 3 :(得分:0)
如果您的控件位于面板等容器内,并且您尝试在容器控件的可见性设置为 false 时更改控件的可见性,则会出现这种行为。