MessageBox.Show有像MessageBox.Show( ownerWindow,... )这样的形式。)。
分配一个所有者窗口有什么好处?
发布于 2008-10-12 15:39:55
消息框是一种模式窗体,这意味着在取消消息框之前,其父窗口将被禁用。
如果调用了不带所有者标识符的Show()重载,则通常会自动选择父窗体。我在文档中找不到任何描述如何选择窗体的内容,但我的经验是,如果消息框显示在GUI线程(即主线程或消息泵线程)中,则该线程的活动窗口将被选作父窗口。
其他线程可能会创建没有父窗体的消息框。这可能是一个糟糕的情况,因为它可能位于活动窗口后面,用户甚至不会知道它在那里,直到他们关闭程序。要避免这种情况,可以将应用程序主窗口的句柄传递给Show方法,该方法将在消息框期间禁用该窗口。
补充道:,我一直在考虑这个问题,现在我不太确定了。你在下面给出的来自reflector的代码片段让我觉得,也许线程并不重要。(我确实说过我在文档中找不到任何东西!)
我必须返回并查看代码以确保这一点,但我认为我以前在主窗体后面丢失的消息框实际上可能是自定义消息框窗体,在这种情况下,我的经验是错误的,并且您永远不需要提供父窗体参数。
很抱歉给你造成了混乱。
我现在的建议是永远不要提供这个参数,除非您需要活动窗口以外的其他东西作为主窗体。
发布于 2008-10-12 15:24:46
设置所有者会导致在消息框打开时禁用所有者。
如果您没有设置所有者,那么用户可以在消息框打开时单击其他内容,甚至关闭所有者,然后当消息框关闭时,调用MessageBox.Show后运行的代码可能处于未知状态-或者,如果所有者被关闭,您现在正在不再存在的窗口中运行代码,任何对WinForms或WPF (或WinAPI和任何其他框架)的方法的调用都可能导致崩溃。
发布于 2014-08-12 02:28:37
基于测试和this other answer,.net将自动选择与MessageBox.Show()调用处于同一线程中的当前焦点窗口。要获得正确的行为,您必须确保从与此窗口相同的线程显示MessageBox,并指定与MessageBox逻辑关联的窗口作为其owner。MessageBox仅以模态方式阻止对启动它的线程上的其他Form的输入。这可能与MessageBox如何使自己成为模式有关(也许它拦截针对当前线程的消息,并且只允许一些消息通过窗口而不是它自己?)。模态阻塞输入的效果是,用户将无法聚焦这些窗口或其中的任何控件,并且尝试这样做会产生"Ding“声音。此外,如果未指定所有者,MessageBox将自动选择当前线程上的活动窗口。如果当前活动的窗口来自不同的线程(或不同的应用程序!),则MessageBox将没有所有者。这意味着它有自己的任务栏条目:它的行为就像它自己的不同窗口。用户可以在您的应用程序中引发其他窗口(即使用户无法与它们交互)。您可能会遇到这样的情况:您的程序停止响应用户输入,而用户感到困惑,因为在显示对话框后,用户以某种方式提升了应用程序的主窗口。但是,如果正确设置了所有者,则尝试提升主窗口将导致MessageBox被提升并闪烁。
要使这一切对子窗口很好地工作,请确保每个子窗口都设置了其Owner属性。如果您调用ShowDialog() (这将使您的自定义Form成为模态的(并且在将owner传递给MessageBox.Show()的相同情况下传递它的owner参数),这将自动发生。
现在,大多数winforms编码都是将代码直接写入Form子类中的事件处理程序。在编写winforms事件处理程序时,您可以假定许多事情。首先,您不应该在图形用户界面事件处理程序中调用this.Invoke()作为顶级语句,因为这样的处理程序总是在创建Form子类时所在的同一线程上运行。其次,对于这些处理程序中的许多处理程序(但不是所有处理程序),您可以假定Form具有焦点(因此MessageBox.Show()会自动选择它作为它的所有者)。例如,当在按钮的Click事件处理程序(可能称为button1_Click)内编写代码时,您可以放心地假定该窗体是有焦点的(因为在另一个窗体的Button上调用PerformClick()是不好的做法)。但是,即使表单没有被聚焦,也可能会发生Timer.Tick。因此,在Timer.Tick的情况下,有no need to Invoke() (just like any other winforms event handler),但有,需要指定owner。后一种情况更容易引起注意,因为开发人员必须将其应用程序置于非焦点状态,才能注意到在这种情况下显示的对话框的行为与其应用程序处于焦点状态时的行为略有不同。因此,只要需要使用owner Invoke() 或,当窗口未被聚焦时可能触发事件时,请指定owner。当调用MessageBox.Show()和Form.ShowDialog()时,适用此准则。
我在这里讨论的大部分内容都是在阅读其他答案时使用的结果。
https://stackoverflow.com/questions/195593
复制相似问题