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

本文关键字:按钮 设置 true Visible 激活 功能 Button | 更新日期: 2023-09-27 18:25:49

我还没有找到其他人有同样的问题,所以希望有人能有一些想法,或者能给我另一个答案。

当通过按下窗体上的按钮来运行函数时,另一个按钮应该可见。然而,按钮永远不会出现,即使它是功能中的第一件事。函数中的所有其他代码都能完美工作。

这是代码:

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

在按钮行之后添加消息框会使按钮在正确的时间出现。

有人知道这个按钮为什么会这样吗?

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

听起来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();

如果控件像面板一样位于容器内,并且当容器控件的可见性设置为false时,您试图更改控件的可见性,则会出现这种行为。