Button.Visible = true; 在function中激活时,无法将按钮设置为可见

我无法找到其他人遇到同样的问题,所以希望有人可能会有一些想法或能够指出我另一个答案。

通过按下表单上的按钮运行function时,另一个按钮应该可见。 但是,即使它是函数中的第一个按钮,按钮也不会显示。 该函数中的所有其他代码都可以正常工作。

这是代码:

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; } 

按钮行后添加消息框导致按钮在正确的时间显示。

有没有人有任何想法为什么这个按钮表现这样?

听起来像GUI线程很忙。 尝试通过调用Application.DoEvents()强制屏幕更新,例如:

 button.Visible = true; progressbar.Visible = true; Application.DoEvents(); 

DoEvents()将强制处理消息队列中的所有消息。

更好的解决方案是移动主UI线程的长时间运行的线程。 使用BackgroundWorker完成任务。

它将使表单整体更具响应性。 例如,您将能够与表单进行交互,并且它不会变为“白色”。 实现BackgroundWorker很简单,对于主UI线程上的长时间运行进程是必须的,

问题是你在UI线程上执行一个长时间运行的进程,因此在线程空闲之前不会将按钮设置为可见。 但是,在线程空闲时,您将visible设置为false。

执行此操作的最佳方法是在后台工作程序上执行长时间运行的进程,以便不阻止UI线程。 进度条工作的原因是因为它在不同的线程上运行。

还有另一种方法 – 但可能不太正确 – 这是在将visible设置为true后在表单上发出Refresh。

如果您需要有关BackgroundWorker的帮助,请告诉我,但它非常直接。

当您运行Windows窗体时,它会创建新窗体,然后等待事件处理。 每次表单处理事件时,它都会处理与该事件关联的所有代码。 所有其他事件在队列中等待。 当您的代码处理事件时,您的应用程序不会响应。 例如,如果在顶部拖动另一个窗口,则窗口不会重新绘制。

如果在代码中调用DoEvents,则应用程序可以处理其他事件。 使用Application.DoEvents();