我听说如果我在没有指定所有者的情况下调用form.ShowDialog(),那么可能会出现我不会在屏幕上看到对话框表单的情况(它会被其他窗口隐藏)。这是真的吗?我使用了ShowDialog()而没有指定所有者数百次,我从来没有遇到任何问题。
您能解释一下我可以在哪种情况下得到所描述的问题吗?
更新
好吧,我做了很多实验,使用ShowDialog()时没有任何实际的意外问题(没有指定所有者)。
所以我认为只是传言ShowDialog()会导致问题。 如果您不同意 - 请给我一个代码示例,请导致问题。
答案 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)
,则表单会按预期显示。