views:

58

answers:

2

I am using Visual Studio 2010, C# .NET 4.0. I have 3 forms: Form1, Form2, Form3.

In Form1 I have a button to open Form2:

private void button1_Click(object sender, EventArgs e)
{
    Form2 f = new Form2();
    f.Show();
}

In Form2 I have a private Form3 variable always pointing to the same Form3:

private Form3 f = new Form3();

And a button to open it as a dialog:

private void button1_Click(object sender, EventArgs e)
{
    f.ShowDialog();
}

In Form3 I just have a button to hide the form:

private void button1_Click(object sender, EventArgs e)
{
    this.Hide();
}

The problem is that having the situation that Form2 is in front of Form1, and Form3 in front of Form2, when I click the button of Form3 to hide it, it not only hides itself but sends Form1 to the back of all of the other Windows.

This ONLY happens when there is a window of another programa (such as Windows Explorer) in the background of Form1. It seems like a bug. What do you think?

+2  A: 

Yes, this cannot work properly by design. A dialog disables all of the windows that your program displays. So that it is modal. When you hide the dialog, there are no windows left that can get the focus. Windows is forced to find another window to give the focus to. That will be a window owned by another application. Your own windows will now hide behind it.

There are more side effects, the dialog will also close. Necessary because otherwise the user can never get back to your program anymore since all windows are disabled. This is all unsurprising behavior. Bug would be a strong word, but it would of course work better if it first re-enabled all windows before closing the dialog. But closing the dialog is already undesirable behavior.

Don't call Hide() for a dialog. Just set the DialogResult property to DialogResult.Cancel to achieve the exact same effect, minus the focus problem. You do have to reset it back to None if you want to display the dialog again. That's a real bug.

Hans Passant
Thanks a lot for you answer. But for me the dialog is not closing. When hidding, it returns control to the owner form (just after ShowDialog call) but I can do another ShowDialog call without problems and the dialog form is restored in the same state. So it was nos closed.
cprcrack
Oh, well, it seems that Closing does not involve disposing, so the form state is saved and the form is really closed but I can just open it again. My fault.
cprcrack
That's quite correct. "Closing" here means that the window is closed, the form object is still alive because it didn't get disposed. And allows recreating the window with ShowDialog.
Hans Passant
@Hans Passant this issue exists even in SQL Management Stuido. Can you recommend any workaround?
Sergey Mirvoda
@Sergey: I gave a good workaround in the bottom of my post. Of course, won't work for SQL Management Studio since you don't have the source code for it. Troubled program, I noticed before. Not sure why you'd hide one of its dialogs though.
Hans Passant
@Hans sorry missed text about DialogResult. as for SQL Studio - just to prove that is known behavior.
Sergey Mirvoda
A: 

By the documentation. Form.Close method don't call the garbage collection for the form shown by Form.ShowDialog method. So, I think there are ways to return focus to your application (it's better to poke around API functions). But it is much more easier to call Form.Close method on dialog windows.

MAKKAM