C# 按钮。可见=真;在功能内激活时,无法将按钮设置为可见

C# 按钮。可见=真;在功能内激活时,无法将按钮设置为可见,c#,winforms,C#,Winforms,我还没有找到其他人有同样的问题,所以希望有人能有一些想法或者能给我指出另一个答案 当通过按下窗体上的按钮来运行函数时,另一个按钮应可见。但是,即使该按钮是函数中的第一项,它也不会显示。函数中的所有其他代码都可以完美地工作 代码如下: private void trackbar_Change(object sender, EventArgs e) { button.Visible = true; progressbar.Visible = true; ... p

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

当通过按下窗体上的按钮来运行函数时,另一个按钮应可见。但是,即使该按钮是函数中的第一项,它也不会显示。函数中的所有其他代码都可以完美地工作

代码如下:

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;
}
在按钮行之后添加消息框导致按钮在正确的时间显示


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

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

最好的方法是在后台工作程序上执行长时间运行的进程,这样UI线程就不会被阻塞。进度条工作的原因是它运行在不同的线程上

还有一种方法——但可能不太正确——那就是在将visible设置为true后对表单进行刷新


如果你需要后台工作人员的帮助,请告诉我,但这很简单

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

button.Visible = true;
progressbar.Visible = true;
Application.DoEvents();
DoEvents()
将强制处理消息队列中的所有消息

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


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

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

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

简短回答,不。这确实很奇怪。。。迫不及待地想听到答案。在
轨迹栏_Change()
过程中,用户界面不会更新,除非它被设置消息框之类的东西阻止。你需要把按钮藏在别的地方。(也许,在进度条的progresscomplete上?)您正在显示它,然后再次隐藏它…您到底希望发生什么事情?
中的代码大约需要15秒才能完成。此外,进度条也隐藏在末尾,功能正常。最好不要建议
DoEvents()
@JeffMercado,我完全同意
DoEvents()
不是正确的方法。但最好是让OP意识到这一点,并与正确的方法进行对比,而不是在DoEvents上绊倒,然后没有更广泛的背景。我认为提到它只是说它是你永远不应该使用的东西是完全可以的。重要的是要理解为什么应该避免。但是,当你给出代码示例来展示它的使用时,你是在为那些不知道如何复制他们看到的第一段代码的人设置一个陷阱。所以我只是说小心点。@PhilipFourie谢谢,这个后台工作人员解决的问题比我知道的要多。现在进度条也工作得更好了。在尝试了backgroundWorkers和线程之后,DoEvents是我在带有.NET CF的windows CE 5设备上唯一可能的解决方案。谢谢