在C#中,ShowDialog()和ShowDialog(IWin32Window)有什么区别?

5

我认为 ShowDialog();ShowDialog(IWin32Window); 看起来做的事情完全一样。文档也不是很清楚。

有人告诉我,ShowDialog(IWin32Window); 会确保对话框窗口位于传递的所有者窗口之上。

MSDN文档没有提到这一点,所以感觉有点像黑魔法。


@XTG 当编辑帖子时,“评论”栏是用来记录你在帖子中进行的编辑内容。请不要写上“由xtg编辑”这样的标记。 - cryptic ツ
5个回答

9

2
我遗漏的部分是ShowDialog()会将当前活动窗口作为父窗口。在大多数情况下,这会导致ShowDialog()和ShowDialog(IWin32Window)的行为相同,至少对于用户来说是这样的。但是,如果您打开了大量窗口,并且在多个线程上运行后台进程并将其调用回UI线程,那么可能会出现一些非常有趣的行为。 - Jonathan Beerhalter
使用WinForms ShowDialog与WPF窗口的帮助程序:http://www.ticklishtechs.net/2009/12/22/how-to-get-a-iwin32window-from-a-wpf-window/ - Dave

5
当调用ShowDialog()方法时,当前活动窗口将成为对话框的所有者。如果您想指定特定的所有者,请使用此方法的其他版本(ShowDialog(IWin32Window))。
这在MSDN文档中已经说明。

http://msdn.microsoft.com/en-us/library/c7ykbedk.aspx


如果所有者(最后一个活动表单)关闭了,模态表单也会关闭。有时很难知道哪个表单是最后一个活动的;它可能是在模态表单之前显示的加载指示器。因此,最好使用ShowDialog(IWin32Window)来指定所有者。您可以在这里看到一个示例。 - fsbflavio

3

ShowDialog() 内部调用带有空参数的 ShowDialog(IWin32Window)。如果参数不为空,则该参数被设置为窗体的所有者。如果所有者为null,则会使用 GetActiveWindow() 获取指向活动窗口的 IntPtr 并将其用作所有者。您可以使用 ILSpy 进行验证。


1
.NET允许一个窗体“拥有”其他窗体。拥有的窗体对于浮动工具箱和命令窗口非常有用。Microsoft Word中查找和替换窗口就是一个拥有的窗体的例子。当所有者窗口最小化时,拥有的窗体也会自动最小化。当拥有的窗体与其所有者重叠时,它总是显示在顶部。
当使用ShowDialog方法时,显示新窗体后,当前活动窗体(称为所有者窗体)和新窗体(称为拥有的窗体)之间建立了一个隐式关系。此关系确保拥有的窗体是活动窗体,并始终显示在所有者窗体的顶部。
该关系的一个特征是:在使用ShowDialog时,拥有的窗体影响其所有者窗体的行为: 1. 所有者窗体无法最小化、最大化或移动。 2. 拥有的窗体阻止鼠标和键盘输入到所有者窗体。 3. 当拥有的窗体被最小化时,所有者窗体也会被最小化。 4. 只有拥有的窗体可以关闭。 5. 如果所有者和拥有的窗体都被最小化,用户按Alt+Tab切换到拥有的窗体,则拥有的窗体将激活。
然而,与ShowDialog方法不同,调用Show方法不会建立一个隐式的所有者-拥有关系。这意味着任何一个窗体都可以成为当前活动窗体。
没有隐式的所有者-拥有关系,所有者和拥有的窗体都可以最小化、最大化或移动。如果用户关闭除主窗体以外的任何窗体,则最近活动的窗体将被重新激活。
虽然ShowDialog建立了一个隐式的所有者-拥有关系,但没有内置的方法让拥有的窗体回调或查询打开它的窗体。在非模态情况下,您可以将新窗体的Owner属性设置为建立所有者-拥有关系。作为一种快捷方式,您可以将所有者窗体作为参数传递给Show方法的重载版本,该方法还接受IWin32Window参数(IWin32Window由通过IWin32Window.Handle属性公开Win32 HWND属性的Windows Forms UI对象实现)。
显式模态所有者-拥有窗体关系中窗体的行为与其隐式模态对应物相同,但是模态拥有者-拥有关系在非所有者-拥有模态案例中提供了额外的行为。首先,无论哪个窗体处于活动状态,模态拥有的窗体始终显示在所有者窗体的顶部。这在需要保持窗口(如浮动工具窗口)在应用程序中的其他窗体上方时很有用。其次,如果用户按Alt+Tab从所有者切换,则所拥有的窗体也会跟随切换。为确保用户知道哪个窗体是主窗体,在最小化所有者窗体时,隐藏所有拥有的窗体的任务栏按钮,只留下所有者的任务栏按钮可见。
(c)《Windows Forms 2.0编程》作者Chris Sells,Michael Weinhardt。

0

frm2.ShowDialog() 将 frm2 设为模态对话框,除非我们关闭 frm2 的实例,否则无法在 form1 上单击任何位置。

frm2.Show() 没有这种限制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接