Reputation: 13519
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.
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).
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.
Upvotes: 45
Views: 64901
Reputation: 874
I found another case where using ShowDialog()
without specify an owner can cause problems. That problem brought me here.
When you have a form that auto-closes (like an loading indicator) that was shown just before the modal form.
In this case, when the loading form closes, it will also close the modal form, as described by @nightcoder answer.
consider the following example:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var form2 = new Form2();
// Config Form2 to close automatically after 2 seconds
var timer2 = new Timer();
timer2.Start();
timer2.Interval = 2000;
timer2.Tick += (s, ev) =>
{
form2.Close();
};
form2.Show();
var form3 = new Form3();
// When Form2 closes, it will close Form3 too, because Form2 owns Form3
// The currently active window (Form2) is made the owner of Form3
// form3.ShowDialog();
// Here, Form1 owns Form3, so when Form2 closes, it does not close Form3
form3.ShowDialog(this);
}
}
I hope it helps someone
Upvotes: 0
Reputation: 61
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.
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.
Upvotes: 3
Reputation: 261
One annoyance I found with 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.
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.
Upvotes: 26
Reputation: 821
I have just found a case where not specifying the owner using this
caused a serious problem.
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.
When I use ShowDialog()
on a custom form the dialog box appears behind my 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.
Upvotes: 0
Reputation: 13519
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.
(c) "Pro .NET 2.0 Windows Forms and Custom Controls" by Matthew MacDonald.
As ShowDialog shows the new form, an implicit relationship is established between 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 Show method 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.
(c) "Windows Forms 2.0 Programming" by Chris Sells, Michael Weinhardt.
Upvotes: 17
Reputation: 1
I had this problem, and to solve it change the windows state property to normal, because maybe its minimized.
Upvotes: 0
Reputation: 12947
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.
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.
Calling ShowDialog(this)
fixes this problem.
Upvotes: 1
Reputation: 11
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.
Upvotes: 1
Reputation: 41116
"Currently active Window" usually refers to the foreground window, but only if it belongs to the current thread - see GetActiveWindow in MSDN.
(The actual information is in the community content, but the commenter is right that there is no "per-thread active window", 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).
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.
Upvotes: 10
Reputation: 7366
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.
Upvotes: 7