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

时间:2012-02-25 03:59:43

标签: c# winforms

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

当按下表单上的按钮运行某个功能时,另一个按钮应该可见。但是,按钮永远不会显示,即使它是函数中的第一件事。该函数中的所有其他代码都可以正常运行。

以下是代码:

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

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

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

4 个答案:

答案 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 时更改控件的可见性,则会出现这种行为。