繁体   English   中英

Form.ShowDialog()或Form.ShowDialog(this)?

[英]Form.ShowDialog() or Form.ShowDialog(this)?

我听说如果我不指定所有者就调用form.ShowDialog(),那么可能会出现在屏幕上看不到对话框窗体的情况(它将被其他窗口隐藏)。 是真的吗 我使用ShowDialog()时没有多次指定所有者,而我从来没有遇到任何问题。

您能说明在哪种情况下我能得到所描述的问题吗?

更新:

好吧,我做了很多实验,但使用ShowDialog()却没有得到任何真正的意外问题(未指定所有者)。

因此,我认为ShowDialog()可能导致问题只是谣言。 如果您不同意,请给我一个代码示例,这会导致问题。

我在ShowDialog()ShowDialog(this)发现了一个烦恼。

运行TestApp,显示newform.ShowDialog() ,在任务栏或“快速启动”工具栏上单击“显示桌面”,在任务栏上单击TestApp。 它显示了Mainform。 您必须做一个Alt-Tab才能进入新表格。

VS

运行TestApp,显示newform.ShowDialog(this) ,在任务栏或“快速启动”工具栏上单击“显示桌面”,在任务栏上单击TestApp。 它在顶部显示新表单。

“当前活动窗口”通常是指前景窗口,但前提是它属于当前线程-请参见MSDN中的GetActiveWindow

(实际信息在社区内容中,但是注释者正确的是,没有“每线程活动窗口”,AFIAK)。

因此,当用户切换到另一个应用程序(或线程)窗口时,最终会出现一些“默认窗口”。 即使.NET在这里做了一些魔术,模态也将被破坏:预期的父窗口不会被禁用(例如,您可以切换到主窗口,然后关闭它,或进行某些修改,这通常会由于重新进入而中断您的应用程序) 。

另外,如果当前有另一个应用程序处于活动状态,则您的对话框将不会显示在顶部,但会隐藏在其他窗口的后面。

作为一个小麻烦,初始位置通常是不正确或具有误导性的。

实际上,这种情况很少发生:如果您响应主菜单上的菜单或按钮单击而打开对话框,则用户实际上几乎不会设法切换到另一个窗口。

但是,从技术上讲,这是可能的,如果您响应某些自动化,外部消息等而打开对话框,则很有可能会发生这种情况。

只是为了更好地了解所有者关系:

.NET允许表单“拥有”其他表单。 拥有的表单对于浮动工具箱和命令窗口很有用。 拥有表单的一个示例是Microsoft Word中的“查找和替换”窗口。 当最小化所有者窗口时,拥有的表单也会自动最小化。 当拥有的表单与它的所有者重叠时,它总是显示在顶部。

(c)Matthew MacDonald撰写的“ Pro .NET 2.0 Windows窗体和自定义控件”。


ShowDialog显示新窗体时,在当前活动窗体(称为所有者窗体)和新窗体(称为拥有窗体)之间建立隐式关系 此关系确保拥有的表单是活动表单,并且始终显示在所有者表单的顶部。

这种关系的一个特点是,所拥有的表单会影响其所有者表单的行为(使用ShowDialog时 ):

  • 所有者表单不能最小化,最大化,甚至不能移动。
  • 拥有的表单会阻止鼠标和键盘输入到所有者表单。
  • 拥有表单为最小时,所有者表单为最小。
  • 只有拥有的表格可以关闭。
  • 如果最小化所有者表单和所有者表单,并且用户按下Alt + Tab切换到所有者表单,则将激活所有者表单。

但是,与ShowDialog方法不同,对Show方法的调用不会建立隐式的所有者拥有的关系 这意味着任何一种形式都可以是当前活动形式。

如果没有隐式的所有者-所有者关系,则可以最小化,最大化或移动所有者和所有者形式。 如果用户关闭除主窗体以外的任何窗体,则最近激活的窗体将重新激活。

尽管ShowDialog建立了隐式的所有者拥有的关系 ,但是没有内置的方式让拥有的表单回叫或查询打开它的表单。 在无模式的情况下,您可以设置新表单的Owner属性以建立所有者拥有的关系。 作为一种快捷方式,您可以将所有者窗体作为参数传递给Show方法的重载,该方法也带有IWin32Window参数(IWin32Window由Windows窗体UI对象实现,该对象通过IWin32Window.Handle属性公开Win32 HWND属性)。

显式模态所有者所有形式关系中的表单行为与其隐式模态对应者相同,但是在非所有者所有无模式情况下,无模所有者拥有关系提供了其他行为。 首先,无模式拥有的表单始终显示在所有者表单的顶部,即使其中一个可以激活。 当您需要将表单(例如浮动工具窗口)保持在应用程序中其他表单之上时,这很有用。 其次,如果用户按Alt + Tab键从所有者切换,则所拥有的表单也将随之效仿。 为了确保用户知道哪个表单是主表单,将所有者最小化将所有所有者表单的任务栏按钮隐藏起来,仅使所有者的任务栏按钮可见。

(c)迈克尔·韦恩哈特(Michael Weinhardt)克里斯·塞尔斯(Chris Sells)撰写的“ Windows Forms 2.0编程”。

无参数的ShowDialog()仅使用“默认”父对象。 对于其价值,默认的父级是“当前活动窗口”的大小。 当您关心父对象是什么时,您需要对其进行显式设置。

请看以下示例:

在主窗体中,您具有一个ListView,并且启用了标签编辑。 编辑特定标签后,您将启动第二个窗口(使用AfterLabelEdit ShowDialog() )。 新表单不会显示在任务栏中。

如果您的用户开始编辑标签,然后单击另一个应用程序,则将显示第二个表单,但是返回到您的应用程序时,该用户仅会看到您的主表单,由于显示了模态对话框,因此已被禁用。 但是,通常的闪烁机制(如果您单击调用者,将使模式对话框显示为字体)将无法工作(肯定是因为AfterEdit调用尚未返回),并且您的用户将无法通过循环进入第二种形式使用Ctrl + Tab打开窗口。

调用ShowDialog(this)解决此问题。

我的问题是从ShowDialog()生成的表单中调用ShowDialog() 结果是一个隐藏的窗体,无法访问以将其关闭。

阅读此主题后,我尝试了ShowDialog(this) ,它运行良好。 第二个对话框显示在顶部,居中且完全可用。 当第二个窗体设置为Dialogresult.OK它允许访问能够读取其属性然后将其关闭的基础对话框。

是的,在某些情况下确实有所不同。 到目前为止,我对无参数方法没有任何问题,并且对父窗体不是默认窗体感到有些惊讶。 因此,为避免意外行为,请始终将真实的父窗体传递给ShowDialog方法。

我遇到了这个问题,要解决此问题,请将Windows状态属性更改为正常,因为它可能已最小化。

我刚刚发现一种情况,其中未指定所有者使用this导致严重问题。

启动后,我的应用程序会强制自己进入全屏模式,并且即使用户试图按Alt + Tab键退出,也要确保它始终具有焦点,除非您以管理员或开发人员身份登录。

当我在自定义窗体上使用ShowDialog() ,由于某种原因该对话框将出现我的应用程序后面 ,并且该应用程序本身由于该对话框当前处于活动状态而变得无法响应。 如果我使用ShowDialog(this)则窗体将按预期显示。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM