Search code examples
c#winformsmdimdichild

Updating MDI child forms list after closing a form


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?


Solution

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