Partager via


ShowDialog() from within a ShowDialog() - both closing

I hit this really weird behavior with Win Forms dialog boxes just now.

Try opening a Dialog Box inside another DialogBox in .NET (1.1 or 2.0) and setting the DialogResult on the second form to be one of the results (OK, Cancel etc). The second dialog box will close, but the first dialog box will also close.

For example, say you have a dialog with two buttons. Button1 opens a new instance of the dialog, and Button2 closes its parent form (the form on which it exists) by setting DialogResult to be DialogResult.OK:

class MyDialog : Form
{
private void Button1_Click(object sender, EventArgs e)
{
new MyDialog().ShowDialog(this);
}

private void Button2_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
}
}

If the user clicks Button1 multiple times and then hits Button2 just once, all the dialog boxes will be closed one after another.

To solve this problem, you need to reset the DialogResult to None after you call a dialog box from another dialog box:

   private void Button1_Click(object sender, EventArgs e)
{
new MyDialog().ShowDialog(this);
DialogResult = DialogResult.None;
}

Not sure for the reason behind this behavior, but there it is... I was stumped there for a few minutes.

Edit: BTW - this only reproes if you set the AcceptButton and CancelButton properties on the form to point to the buttons you created. Apparently that's the trigger that manifests the bug.

Comments

  • Anonymous
    October 03, 2005
    The comment has been removed

  • Anonymous
    October 03, 2005
    Gabe,

    Hmm..
    Not sure I follow.

    I am not doing anything with the DialogResult in Button1 - that's intentional. Even if I did assign it to a local variable and read it, the behavior would be identical.

    The only problem here, that I can see, is that the value somehow gets propagated to the parent, like you say. This behavior was not in VB6, VB5, VB4, Access 2.0, Access 95, MFC or even WTL (from what little I used WTL).

    I dont think this is a backward compatibility issue.

  • Anonymous
    October 04, 2005
    I'm glad someone else has hit this bug too!

    How about we get this one, and the one where if you have a dialog open and you show another dialog and then close that dialog the next available application in the task manager will get the focus? It's not like it hasn't been around for long enough, it's been there since VB3 and probably earlier....

  • Anonymous
    September 26, 2006
    > I was stumped there for a few minutes.

    Just a few minutes? ;-)

    Thanks for that hint.

    In this case I definitelay dodn't understand thsi behavior...

  • Anonymous
    October 14, 2007
    Hi Shahar Thanks a lot for this tip, I was really quite stumped. Cheers, Patrick

  • Anonymous
    June 26, 2008
    Thanks! Yes, this code works  as described above to prevent the second underlying form from closing in a string of showdialogs when placed after the calling showdialog.  Thanks.      DialogResult = DialogResult.None; This string is just so other people can google this solution easier: " Showdialog closes form when it should not "

  • Anonymous
    November 22, 2010
    This still hasn't been fixed in .NET 4. Wasted almost a day to figure it out :-(

  • Anonymous
    April 07, 2011
    ??? InnerDialog inner = new InnerDialog()    DialogResult innerResult = inner.ShowDialog(this);    this.DialogResult = DialogResult.None;

  • Anonymous
    July 19, 2011
    I got bitten by this because I had copy/pasted some buttons from another form, not realizing that one of the buttons had it's DialogResult property set to DialogResult.Cancel. When clicked, this was setting the containing form's DialogResult, causing it to close. Resetting it to DialogResult.None fixed the problem. So, check the DialogResult properties on all your modal dialogs.

  • Anonymous
    October 28, 2015
    Thanks! Thanks! Thanks a million! I was struggling with that! that's the key. DialogResult is assigned to the ShowDialog Function of the form. Worked for me to set it to none!