Updating MDI child forms list after closing a form

952 views Asked by At

I am using DevExpress NavBar as main menu for my MDI application, and one of NavBar's groups contains items that represent opened MDI child forms. I am having trouble with updating a menu when a MDI child form closes.

I have to use Form.MdiChildren collection to generate menu group, but the problem is, when using Form.FormClosing event, that closed form is still in Form.MdiChildren collection. I tried to use a System.Timers.Timer to wait 1 second and then update a menu, but I get various exceptions because of asynchronous behavior (when a user closes few forms very fast).

I also cannot maintain my own list of MDI children, because of complexity of classes design.

Does anyone have some elegant solution for this?

2

There are 2 answers

3
DonBoitnott On BEST ANSWER

I have had success with using this combination of methods:

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

protected override void OnMdiChildActivate(EventArgs e)
{
   base.OnMdiChildActivate(e);

   Form form = ActiveMdiChild;
   if (form == null)
       return;
   else
   {
       if (!_childForms.Contains(form))
       {
           _childForms.Add(form);
           form.FormClosed += mdiChildForm_FormClosed;
       }
   }
}

private void mdiChildForm_FormClosed(Object sender, FormClosedEventArgs e)
{
   var form = (Form)sender;
   if (_childForms.Contains(form))
       _childForms.Remove(form);
   if (_childForms.Count > 0)
       _childForms[_childForms.Count - 1].Activate();
}

Note that the Activate method is called pretty much anytime the user interacts with a child form. That includes opening and closing them.

You can then make use of the childForms collection to always know the open forms and do what you like with them.

1
Jeroen van Langen On

"I also cannot maintain my own list of MDI children, because of complexity of classes design."

Is this because of the different class types? What about holding a list of base classes? like: List<Form> When there is a FormClosed event, just remove that form from the list.