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

时间:2009-05-03 12:03:13

标签: c# .net winforms

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

您能解释一下我可以在哪种情况下得到所描述的问题吗?

更新

好吧,我做了很多实验,使用ShowDialog()时没有任何实际的意外问题(没有指定所有者)。

所以我认为只是传言ShowDialog()会导致问题。 如果您不同意 - 请给我一个代码示例,请导致问题。

9 个答案:

答案 0 :(得分:20)

我在ShowDialog() vs ShowDialog(this)找到了一个烦恼。

运行TestApp,显示newform.ShowDialog(),单击任务栏上的“show Desktop”或快速启动工具栏,单击任务栏上的TestApp。它显示了Mainform。你必须做一个Alt-Tab才能进入你的新形态。

VS

运行TestApp,显示newform.ShowDialog(this),单击任务栏上的“show Desktop”或快速启动工具栏,单击任务栏上的TestApp。它显示了新形式。

答案 1 :(得分:8)

“当前活动窗口”通常是指前台窗口,但仅当它属于当前线程时 - 请参阅MSDN中的GetActiveWindow

(实际信息在社区内容中,但是评论者说没有“每线程活动窗口”,AFAIK)。

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

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

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

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

但是,这在技术上是可行的,并且如果您打开对话框以响应某些自动化,外部消息等,很可能会发生这种情况。

答案 2 :(得分:7)

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

  

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

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


  

ShowDialog 显示新表单时,隐式关系是   在当前活动表单之间建立,称为所有者   形式和新形式,称为自有形式。这种关系   确保拥有的表单是活动表单并始终显示   所有者表单的顶部。

     

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

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

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

     

没有隐含的所有者拥有的关系,所有者和拥有的表单   同样可以最小化,最大化或移动。如果用户关闭任何   除主要形式以外的形式,最近活跃的形式是   重新激活。

     

虽然 ShowDialog建立隐式所有者拥有的关系,   所拥有的表单没有内置的方式来回调或查询   打开它的形式。在无模式的情况下,您可以设置新的   form的所有者财产,以建立所有者拥有的关系。作为一个   快捷方式,您可以将所有者表单作为参数传递给重载   Show方法,它也采用IWin32Window参数   (IWin32Window由公开的Windows窗体UI对象实现   Win32 HWND属性通过IWin32Window.Handle属性)。

     

表单在显式模式所有者拥有的表单中的行为   关系与其隐式模态对应关系相同,但是   无模式的所有者拥有的关系提供了额外的行为   非所有者拥有的无模式案件。首先,无模式拥有的形式总是如此   出现在所有者表单的顶部,即使其中任何一个都可以处于活动状态。   当您需要保留表单(例如浮动工具)时,这非常有用   窗口,位于应用程序中的其他窗体之上。第二,如果   用户按Alt + Tab从所有者切换,拥有的表单跟随   适合。为了确保用户知道哪个表单是主表单,   最小化所有者隐藏所有自有表单的任务栏按钮,   只留下所有者的任务栏按钮。

(c)Chris Sells的“Windows Forms 2.0 Programming”,Michael Weinhardt。

答案 3 :(得分:5)

无参数的ShowDialog()只使用“默认”父级。 对于它的价值,默认父级是“当前活动窗口”。当你关心父母是什么时,你需要明确地设置它。

答案 4 :(得分:1)

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

答案 5 :(得分:1)

采用以下示例:

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

如果您的用户开始编辑标签,然后点击另一个应用程序,则会显示第二个表单,但是当返回到您的应用程序时,用户将只显示您的主表单,因为显示模式对话框而被禁用。然而,通常的闪烁机制(如果单击调用者将模式对话框带入字体)将无法正常工作(当然因为AfterEdit调用尚未返回),并且您的用户将无法访问第二个表单,除非通过循环通过使用Ctrl + Tab打开窗口。

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

答案 6 :(得分:1)

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

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

答案 7 :(得分:0)

我有这个问题,并解决它将Windows状态属性更改为正常,因为它可能是最小化的。

答案 8 :(得分:0)

我刚刚发现一个案例,即未使用this指定所有者导致严重问题。

启动后,我的应用程序强制自动全屏显示,并确保它始终具有焦点,即使用户尝试使用Alt + Tab,除非您以管理员或开发人员身份登录。

当我在自定义表单上使用ShowDialog()时,由于某种原因,对话框在我的应用程序后面出现,并且应用程序本身变得没有响应,因为对话框当前处于活动状态。如果我使用ShowDialog(this),则表单会按预期显示。