Issa Jaber
Issa Jaber

Reputation: 409

Stackoverflow Exception closing Form

I have a problem in WinForms. I created a MDIParent-Form and i call a ChildForm from the Load of the MDIParent. And I want that if the ChildForm closes, the MDIParent must close and the Application exits. Thats why i wrote an event for the childForm in the MDIParent, so that if the ChildForm closes the FormClosed-Event would be fired in the MDIParent, but it throws a stack overflow exception. I know that there is a infinite loop, but I dont know why...

   private void MDIParent1_Load(object sender, EventArgs e)
    {
        Form1 childForm = new Form1();
        childForm.MdiParent = this;
        childForm.FormClosed += childForm_FormClosed;
        childForm.Show();
    }

    void childForm_FormClosed(object sender, FormClosedEventArgs e)
    {
        this.Close(); 
        //{Cannot evaluate expression because the current thread is in a stack overflow state.}
    }

but if i use

  Application.Exit();

instead of this.Close()... everything works fine ... i want to know why...can someone explain??

Update: I have tried the same without a MDIParent and everything works...but why is there a problem if I use a MDIParent

Upvotes: 5

Views: 3094

Answers (1)

Hans Passant
Hans Passant

Reputation: 941317

This is a bit of a bug, the problem is that the child still is present in the MDIParent1.MdiChildren collection when the FormClosed event fires. In other words, the FormClosed event fires a little too soon. So when you close the parent, it will try to close the child again. Which triggers the child's FormClosed event again. Which closes the parent again. Etcetera. Event firing order is never not a problem. Well, let's call it a bug :)

The workaround is to use the Disposed event instead, it fires later:

private void MDIParent1_Load(object sender, EventArgs e)
{
    Form1 childForm = new Form1();
    childForm.MdiParent = this;
    childForm.Disposed += childForm_Disposed;
    childForm.Show();
}

void childForm_Disposed(object sender, EventArgs e)
{
    this.Close();   // Fine now
}

Upvotes: 6

Related Questions