3

不久前,我遇到了一种情况,我们需要向用户显示消息框以获取通知,但我们无法使用 MessageBox.Show,因为它阻塞了 GUI 线程(因此,当对话框处于活动状态时,屏幕上的任何内容都不会更新)。关于替代方案的任何建议?

[我当时编写了一个替代方案,但我不喜欢它。如果没有更好的情况出现,我会将其作为答案发布]

编辑:对话框必须浮动在主窗口的顶部;我不在乎它是否出现在任务栏中。在某些情况下,可能会同时激活多个对话框。

附录:我的解决方案是一个基本表单,它提供了 OK 和 CANCEL 按钮来发出 Completed 和 Canceled 事件;OK 为子类覆盖调用了一个虚拟 ValidateData。调用表单使用属性来避免每次重新创建表单(表单只是隐藏而不是关闭)并保留活动表单的字典以防止多次激活同一表单。这看起来像一个模态窗体,一次支持多个弹出窗体,但不占用主 GUI 线程。

4

7 回答 7

4

我同意 rslite 和 Mitchel Sellers 的观​​点。创建一个非模态表单来显示所需的信息是最好的方法。如果您有多个消息,您可能需要考虑将它们放入 ListBox 并让用户双击它们以获取需要显示的完整信息。

于 2008-10-13T20:30:11.587 回答
4

我建议像其他人所说的那样采用非模态方法,但更具体一点:

  • 如果您只想要一个通知,您可以尝试一个气球提示(TNA 或您自己的),或者一个类似于 Outlook 邮件通知的窗口或许多即时消息程序(如 Trillian 显示)的通知。
  • 如果您只是想给用户一个行动的机会,请使用非模态表单,但请记住他很可能只是单击它即可。
  • 如果用户必须对您的消息采取行动,您应该使用模态。请注意,所有者窗口仍将被绘制并且您可以刷新您的 GUI - 模式对话框毕竟有一个消息泵,否则它将无法工作。我最近做了类似的事情,我们有一个后台工作线程池,它可以执行任何操作和触发事件以使 GUI 刷新,以及一个模式等待对话框,它仍然得到它的消息泵。所有者窗口确实按预期使用后台操作进行了更新。
于 2008-10-13T20:49:42.343 回答
2

NotifyIcon添加到您的应用程序并显示气球提示怎么样。不利的一面是通知会在短时间内消失,但如果他们不需要采取行动,这对您的用户来说可能是最好的。

于 2010-05-14T18:18:43.070 回答
1

我会根据具体要求使用非模态对话框或一些工具提示来解决这个问题。

于 2008-10-13T20:14:10.980 回答
1

如果您不希望它阻塞,我只需创建您自己的简单表单来进行显示。这就是我在需要非阻塞解决方案之前为客户完成项目的方式。但是请记住,如果您以非阻塞方式进行操作,那么如果用户真的是“您必须采取行动”类型的项目,那么用户可能会获得倍数并不知所措。

于 2008-10-13T20:16:17.327 回答
1

感谢所有提供建议的人,看来我的解决方案是正确的;-)

我的解决方案是一个基本表单,它提供了 OK 和 CANCEL 按钮来发出 Completed 和 Canceled 事件;OK 为子类覆盖调用了一个虚拟 ValidateData。调用表单使用属性来避免每次重新创建表单(表单只是隐藏而不是关闭)并保留活动表单的字典以防止多次激活同一表单。这看起来像一个模态窗体,一次支持多个弹出窗体,但不占用主 GUI 线程。

于 2008-11-13T05:22:57.387 回答
-1

如果您想要 MessageBox 的外观和感觉,只需在后台线程中显示它。

ThreadPool.QueueUserWorkItem( (state) =>
    {
         MessageBox.Show("Your message");
    });

(代码未测试)

于 2008-10-13T20:34:26.603 回答