8

使用 Winforms,如果我在一个不是“主”ui 线程的线程上,我可以安全地

  1. 创建一个表格,
  2. 在该表单上调用 ShowDialog

似乎我会遵守以下规则:必须在创建它们的线程上修改 Winforms 控件。

从我所做的一些阅读来看,ShowDialog 似乎会创建自己的消息泵,这样我就不必担心在已经有消息泵的线程上创建表单。

问题的背景是我收到一个回调,我想在其中显示一些 Winforms UI,但我无权访问可用于调用主线程的任何其他 UI。

4

2 回答 2

7

这大致正确,尽管调用线程的 SetApartmentState() 方法将线程切换到 STA 非常重要。对许多 UI 操作很重要,包括剪贴板、拖放和 shell 对话框。当您在线程上创建的表单不在前台并隐藏在另一个窗口后面时,您通常会遇到糟糕的 Z 顺序问题。或者当用户没有预料到它并意外地抓住鼠标点击或击键时,实际上确实在前台移动了令人讨厌的习惯。

这些是很难解决的问题,它们确实会使您的应用程序变得不稳定。没有充分的理由没有引用来调用,您也可以通过某种方式将其传递给类。如果真的有必要,您总是可以使用 Application.OpenForms[0]。

于 2012-06-06T00:03:08.467 回答
2

是的,您可以这样做,但是如果您希望对话框实际上像模态对话框一样运行(即,阻止父窗口,我假设您想要这样做,因为您正在调用ShowDialog)然后准备好失望。

您实际上要在这里解决什么问题。听起来您想要一个不阻塞的模态对话框,这有点奇怪。如果您解释手头的问题,则可能存在您尚未考虑的解决方案。

于 2012-06-05T22:51:43.477 回答