views:

1579

answers:

3

Is there an event I can use to tell if a child form has been added or removed from the MDI parent?

+4  A: 

Yes. On your main MDI form, wire up to the MdiChildActivated Event.

Like so:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.MdiChildActivate += new EventHandler(Form1_MdiChildActivate);
        }

        void Form1_MdiChildActivate(object sender, EventArgs e)
        {
            MessageBox.Show("Activated");
        }

        private void addToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form form2 = new Form2();
            form2.MdiParent = this;
            form2.Show();
        }
    }

And that event will fire when the child form is both activated or deactivated.

Chris Holmes
how can I tell if it's coming or going? Just check the list of children and see if sender is there?
Malfist
Humm, that may not work. If I reactivate/focus an open form it also throws the event.
Malfist
I got it, an ID field in the base class for all the children.
Malfist
Your MDI form will also have an array of children. The property is MdiChildren. You can check the count of that list to know whether a form was just added, removed, or focused (count would stay the same).
Chris Holmes
good point! Easier to implement and maintain too
Malfist
No, that doesn't seem to work...
Malfist
It's because the MdiChildren collection doesn't get updated until the child form is completely gone. In other words, MdiChildActivated fires before the child goes away. So it works for detecting when a form is added, but it lags one behind when a form is removed.
Chris Holmes
+2  A: 

No, there is not. You would have to subclass Form and expose specific events that would indicate when the child is added and then route all attachments of child forms through a method that would wire up the child form, as well as raise the event.

casperOne
Would you explain how to do this?
Malfist
@Malfist: You would extend Form, add an AddMdiChild method, and then when it is called, you would set the MdiParent of the form passed in to itself, and then fire the event.
casperOne
How would I tell if a child closed?
Malfist
@Malfist: Attach to the Closed/Closing events on the child when AddMdiChild is called.
casperOne
But the children would have their own Closed/Closing events, can I add another event handler?
Malfist
@Malfist: You would not be replacing it. The event handler would be added on to any that already existed.
casperOne
+1  A: 

Wire up the MdiChildActivate event and keep a list of recognized children. When a new form is activated, also wire up the FormClosed event.

private List<Form> ChildFormList = new List<Form>();

private void MyForm_MdiChildActivate(object sender, EventArgs e)
{
    Form f = this.ActiveMdiChild;

    if (f == null)
    {
        //the last child form was just closed
        return;
    }

    if (!ChildFormList.Contains(f))
    {
        //a new child form was created
        ChildFormList.Add(f);
        f.FormClosed += new FormClosedEventHandler(ChildFormClosed);
    }
    else
    {
        //activated existing form
    }
}

private void ChildFormClosed(object sender, FormClosedEventArgs e)
{
    //a child form was closed
    Form f = (Form)sender;
    ChildFormList.Remove(f);
}
lc