【问题标题】:Form.Invoke() does not run when form is hidden,Form.Invoke() 在表单隐藏时不运行,
【发布时间】:2012-09-18 00:35:49
【问题描述】:

如果我采用 C# 表单 (WinForms) 并使其不可见:

MyForm.Visible = false;

然后在我创建的单独线程中;执行以下代码:

        this.Invoke(new MethodInvoker(delegate()
                                          {
                                              ProgressBar2.Visible = false;
                                          }));

我的应用程序将冻结而不继续。如果 MyForm 可见,则线程中的上述代码运行良好。如果它不可见,则代码在读取“this.Invoke(new MethodInvoker(delegate())”行后立即停止运行。它不会出错,它只是坐在那里(我设置了一个断点来观察它就在“this.Invoke(new MethodInvoker(delegate()”)之后坐在那里。

知道为什么当我的表单被隐藏时它不会执行吗?以及如何解决这个问题?我正在使用“this.Invoke(new MethodInvoker(delegate()”),因为我需要能够将 MainForm 上的进度条控件设置为可见(并且我必须在主 UI 线程之外的另一个线程上执行此操作)并且我想要无论表单是否可见,都要这样做。

【问题讨论】:

  • 我不知道答案,但我有类似的情况,我认为当表单对象被隐藏时,您无法更改它的视觉样式或它的控件。再次假设真的不知道。
  • 嗯...试试 BeginInvoke()。除非绝对必要,否则我不喜欢发布同步 UI 更新。也就是说,我不知道为什么你的代码不起作用。无法聚焦已禁用/隐藏的控件,但进度条无论如何都无法获得焦点。我很惊讶没有在某处抛出异常。如果你在'ProgressBar2.Visible = false'周围放置一个try/catch会发生什么?
  • @Star - 你可能是对的,但我正在努力寻找任何合理性。如果一个组件由于其父级被隐藏而无法实际呈现,那么只有一些内部布尔数据成员会在 setter 方法中被更改,并且当稍后再次显示表单时该组件将被正确呈现。这听起来像是它应该如何工作,但我不确定。

标签: c# multithreading


【解决方案1】:

当表单被隐藏时,我相信消息泵不再运行。我知道 Invoke 机制需要运行消息泵。

您可以通过将不透明度设置为 0 而不是可见性来解决此问题,但这有其自身的问题。

【讨论】:

  • 我非常怀疑。如果仅仅因为表单被隐藏就无法将消息发送到表单,那么就无法再次使其可见!
【解决方案2】:

将您的表单包装在一个元素中并设置其样式="display:none;"。将 visible 设置为 false 会导致对象不在客户端代码中呈现。

【讨论】:

  • OP 不要求渲染 - 更改隐藏表单上组件的“隐藏”属性应该没问题 - 它只是不会被渲染。只是我对此的“本能”-不知道答案。你可能是对的,只是感觉不对..
  • 他似乎想对一个他不想看到的对象采取行动。使用客户端隐藏与服务器端可见允许消息泵继续工作,因为对象仍呈现客户端。我同意这似乎并不完全合乎逻辑,但它确实有效。
猜你喜欢
  • 2018-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多