0
votes

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

2 Answers

1
votes

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.

0
votes

"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.