C# Form.ShowDialog() 还是 Form.ShowDialog(this)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/816885/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Form.ShowDialog() or Form.ShowDialog(this)?
提问by nightcoder
I heard that if I call form.ShowDialog() without specifying the owner, then there can be a case when I will not see the dialog form on screen (it will be hidden with other windows). Is it true? I used ShowDialog() without specifying the owner hundreds of times and I never had any problems with that.
我听说如果我在不指定所有者的情况下调用 form.ShowDialog() ,那么可能会出现在屏幕上看不到对话框窗体的情况(它将被其他窗口隐藏)。这是真的吗?我在没有指定所有者的情况下使用 ShowDialog() 数百次,我从来没有遇到任何问题。
Can you please explain in which situation I could get the described problem?
你能解释一下在哪种情况下我会遇到所描述的问题吗?
UPDATE:
更新:
Well, I did many experiments and I couldn't get any real unexpected problems with using ShowDialog() (without specifying the owner).
好吧,我做了很多实验,但使用 ShowDialog()(没有指定所有者)没有遇到任何真正的意外问题。
So I think it's just rumors that ShowDialog() can lead to problems. If you don't agree - give me a code sample please that leads to a problem.
所以我认为 ShowDialog() 可能会导致问题只是谣言。如果您不同意 - 请给我一个代码示例,这会导致问题。
采纳答案by nightcoder
Just to better understand the owner-owned relationship:
只是为了更好地理解所有者拥有的关系:
.NET allows a form to “own” other forms. Owned forms are useful for floating toolbox and command windows. One example of an owned form is the Find and Replace window in Microsoft Word. When an owner window is minimized, the owned forms are also minimized automatically. When an owned form overlaps its owner, it is always displayed on top.
.NET 允许一个表单“拥有”其他表单。拥有的窗体对于浮动工具箱和命令窗口很有用。拥有表单的一个示例是 Microsoft Word 中的“查找和替换”窗口。当所有者窗口最小化时,拥有的窗体也会自动最小化。当拥有的表单与其所有者重叠时,它始终显示在顶部。
(c) "Pro .NET 2.0 Windows Forms and Custom Controls" by Matthew MacDonald.
(c) Matthew MacDonald 的“Pro .NET 2.0 Windows 窗体和自定义控件”。
As ShowDialogshows the new form, an implicit relationship is establishedbetween the currently active form, known as the owner form, and the new form, known as the owned form. This relationship ensures that the owned form is the active form and is always shown on top of the owner form.
One feature of this relationship is that the owned form affects the behavior of its owner form (when using ShowDialog):
- The owner form cannot be minimized, maximized, or even moved.
- The owned form blocks mouse and keyboard input to the owner form.
- The owner form is minimized when the owned form is.
- Only the owned form can be closed.
- If both owner and owned forms are minimized and if the user presses Alt+Tab to switch to the owned form, the owned form is activated.
Unlike the ShowDialog method, however, a call to the Showmethod does not establish an implicit owner-owned relationship. This means that either form can be the currently active form.
Without an implicit owner-owned relationship, owner and owned forms alike can be minimized, maximized, or moved. If the user closes any form other than the main form, the most recently active form is reactivated.
Although ShowDialog establishes an implicit owner-owned relationship, there is no built-in way for the owned form to call back to or query the form that opened it. In the modeless case, you can set the new form's Owner property to establish the owner-owned relationship. As a shortcut, you could pass the owner form as an argument to an overload of the Show method, which also takes an IWin32Window parameter (IWin32Window is implemented by Windows Forms UI objects that expose a Win32 HWND property via the IWin32Window.Handle property).
The behavior of forms in an explicit modal owner-owned form relationship is the same as its implicit modal counterpart, but the modeless owner-owned relationship provides additional behavior in the non-owner-owned modeless case. First, the modeless owned form always appears on top of the owner form, even though either can be active. This is useful when you need to keep a form, such as a floating tool window, on top of other forms within an application. Second, if the user presses Alt+Tab to switch from the owner, the owned forms follow suit. To ensure that the user knows which form is the main form, minimizing the owner hides the task bar buttons for all owned forms, leaving only the owner's task bar button visible.
当ShowDialog显示新表单时,在当前活动的表单(称为所有者表单)和新表单(称为拥有的表单)之间建立了隐式关系。这种关系确保拥有的表单是活动表单,并且始终显示在所有者表单的顶部。
这种关系的一个特点是拥有的表单会影响其拥有者表单的行为(使用ShowDialog 时):
- 所有者窗体不能最小化、最大化,甚至移动。
- 拥有的表单阻止鼠标和键盘输入到拥有者表单。
- 当拥有的表单最小化时,所有者表单被最小化。
- 只能关闭拥有的表单。
- 如果所有者和拥有的表单都最小化,并且如果用户按 Alt+Tab 切换到拥有的表单,则激活拥有的表单。
然而,与 ShowDialog 方法不同的是,对Show方法的调用不会建立隐式所有者拥有关系。这意味着任一表单都可以是当前活动的表单。
如果没有隐式的所有者拥有关系,所有者和拥有的表单都可以被最小化、最大化或移动。如果用户关闭主窗体以外的任何窗体,则重新激活最近活动的窗体。
尽管ShowDialog 建立了一个隐式的所有者拥有关系,但拥有的表单没有内置的方式来回调或查询打开它的表单。在无模式情况下,您可以设置新表单的 Owner 属性来建立所有者拥有的关系。作为一种快捷方式,您可以将所有者窗体作为参数传递给 Show 方法的重载,该方法还采用 IWin32Window 参数(IWin32Window 由通过 IWin32Window.Handle 属性公开 Win32 HWND 属性的 Windows 窗体 UI 对象实现)。
显式模态所有者拥有表单关系中的表单行为与其隐式模态对应关系相同,但无模态所有者所有关系在非所有者拥有的无模态情况下提供了额外的行为。首先,无模式拥有的窗体总是出现在所有者窗体的顶部,即使两者都可以是活动的。当您需要在应用程序中的其他表单之上保留一个表单(例如浮动工具窗口)时,这非常有用。其次,如果用户按 Alt+Tab 从所有者切换,则拥有的表单也会效仿。为了确保用户知道哪个表单是主表单,最小化所有者隐藏所有拥有的表单的任务栏按钮,只留下所有者的任务栏按钮可见。
(c) "Windows Forms 2.0 Programming" by Chris Sells, Michael Weinhardt.
(c) Chris Sells、Michael Weinhardt 撰写的“Windows Forms 2.0 编程”。
回答by Iralda Mitro
The parameterless ShowDialog() simply uses a "default" parent. For what it's worth, the default parent is whatever the "currently active window" is. When you care what the parent is, you need to set it explicitly.
无参数 ShowDialog() 仅使用“默认”父级。就其价值而言,默认父级是“当前活动窗口”的任何内容。当您关心父对象是什么时,您需要明确设置它。
回答by peterchen
"Currently active Window" usually refers to the foreground window, but only if it belongs to the current thread - see GetActiveWindowin MSDN.
“当前活动窗口”通常指的是前台窗口,但前提是它属于当前线程 - 请参阅MSDN 中的GetActiveWindow。
(The actual information is in the community content, but the commenter is right that there is no "per-thread active window", AFAIK).
(实际信息在社区内容中,但评论者是对的,没有“每线程活动窗口”,AFAIK)。
So when the user switched to another applications (or threads) window, you end up with some "default window". Even if .NET does some magic here, the modality will be broken: the intended parent window does not get disabled (e.g. you could switch to your main window, and close it, or modify something, which often breaks your application due to reentrancy).
因此,当用户切换到另一个应用程序(或线程)窗口时,您最终会得到一些“默认窗口”。即使 .NET 在这里做了一些魔法,模式也会被破坏:预期的父窗口不会被禁用(例如,您可以切换到主窗口,然后关闭它,或修改某些内容,这通常会由于可重入而破坏您的应用程序) .
Also, if another application is currently active, your dialog will not be shown on top, but it will be hidden behind some other window.
此外,如果另一个应用程序当前处于活动状态,您的对话框将不会显示在顶部,但它会隐藏在其他某个窗口后面。
As a minor annoyance, the initial position is usually incorrect or misleading.
作为一个小烦恼,初始位置通常不正确或具有误导性。
In practive, this happens rarely, though: if you open the dialog in response to a menu or button click on your main window, the user doesn't will virtually never manage to switch to another window.
但实际上,这种情况很少发生:如果您打开对话框以响应主窗口上的菜单或按钮单击,则用户实际上永远不会切换到另一个窗口。
However, it is technically possible, and quite likely to happen if you open the dialog in response to some automation, external message etc.
但是,这在技术上是可能的,并且如果您打开对话框以响应某些自动化、外部消息等,则很可能会发生。
回答by Sun
One annoyance I found with ShowDialog()
vs ShowDialog(this)
.
我发现ShowDialog()
vs 的一个烦恼ShowDialog(this)
。
Run the TestApp, show the newform.ShowDialog()
, click "show Desktop" on your taskbar or Quick launch toolbar, click on the TestApp on the taskbar. It shows the Mainform. You have to do an Alt-Tab to get to your newform.
运行 TestApp,显示newform.ShowDialog()
,单击任务栏或快速启动工具栏上的“显示桌面”,单击任务栏上的 TestApp。它显示了 Mainform。您必须按 Alt-Tab 才能进入新表单。
VS
VS
Run the TestApp, show the newform.ShowDialog(this)
, click "show Desktop" on your taskbar or Quick launch toolbar, click on the TestApp on the taskbar. It shows the newform on top.
运行 TestApp,显示newform.ShowDialog(this)
,单击任务栏或快速启动工具栏上的“显示桌面”,单击任务栏上的 TestApp。它在顶部显示新表单。
回答by PhantomLord
Yes, it does make difference in some cases. I had no problem with parameterless method until now, and I was a bit surprised that the parent form was not the default form. So, to avoid unexpected behavior, always pass the real parent form to ShowDialog method.
是的,它在某些情况下确实有所不同。直到现在我对无参数方法没有任何问题,而且我有点惊讶父表单不是默认表单。因此,为了避免意外行为,始终将真正的父窗体传递给 ShowDialog 方法。
回答by Clément
Take the following example:
以下面的例子为例:
In your main form, you have a ListView, with label editing enabled. When a specific label is edited, you launch a second window, (using ShowDialog()
in AfterLabelEdit
). The new form doesn't show in the task bar.
在您的主表单中,您有一个 ListView,启用了标签编辑。编辑特定标签后,您将启动第二个窗口(使用ShowDialog()
in AfterLabelEdit
)。新表单不会显示在任务栏中。
If your user starts editing the label, then clicks on another application, then the second form will show, but when returning to your application the user will only be presented with your main form, disabled since a modal dialog is showing. Yet, the usual blinking mechanism (which brings the modal dialog to font if you click the caller) will not work (surely because the AfterEdit call has not returned yet), and your user will not be able to reach the second form except by cycling through open windows using Ctrl+Tab.
如果您的用户开始编辑标签,然后单击另一个应用程序,则会显示第二个表单,但是当返回到您的应用程序时,用户只会看到您的主表单,由于显示了模态对话框而被禁用。然而,通常的闪烁机制(如果您单击调用者,它将使模式对话框变为字体)将不起作用(肯定是因为 AfterEdit 调用尚未返回),并且您的用户将无法访问第二个表单,除非循环通过使用 Ctrl+Tab 打开的窗口。
Calling ShowDialog(this)
fixes this problem.
调用ShowDialog(this)
解决了这个问题。
回答by Zaher Ahmad Al-Bluwe
I had this problem, and to solve it change the windows state property to normal, because maybe its minimized.
我遇到了这个问题,为了解决它,将 Windows 状态属性更改为正常,因为它可能已最小化。
回答by valsidalv
I have just found a case where not specifying the owner using this
caused a serious problem.
我刚刚发现一个案例,未指定所有者使用会this
导致严重问题。
Upon launch my application forces itself to go fullscreen and also makes sure it always has focus, even if the user tries to Alt+Tab out of it, unless you log in as an administrator or developer.
启动时,我的应用程序会强制自己全屏显示,并确保它始终具有焦点,即使用户尝试按 Alt+Tab 键退出它,除非您以管理员或开发人员身份登录。
When I use ShowDialog()
on a custom form the dialog box appears behindmy application for some reason, and the application itself becomes unresponsive because the dialog box is currently active. If I use ShowDialog(this)
then the form shows up as intended.
当我ShowDialog()
在自定义表单上使用时,出于某种原因,对话框出现在我的应用程序后面,应用程序本身变得无响应,因为对话框当前处于活动状态。如果我使用,ShowDialog(this)
那么表单会按预期显示。
回答by tjmaher
My problem was to call ShowDialog()
from a form that was brought up with ShowDialog()
. The result was a hidden form with no way to access it to close it.
我的问题是ShowDialog()
从带有ShowDialog()
. 结果是一个隐藏的表单,无法访问它来关闭它。
After reading this topic, I tried ShowDialog(this)
and it worked perfectly. The second dialog showed on top, centered, and completely functional. When the second form was set to Dialogresult.OK
it allowed access to the underlying dialog which was able read its properties and then close it.
阅读完这个话题后,我试了ShowDialog(this)
一下,效果很好。第二个对话框显示在顶部,居中且功能齐全。当第二个表单设置为Dialogresult.OK
它时,它允许访问能够读取其属性然后关闭它的底层对话框。