MDI Form detecting with a child form is added or r

2020-02-14 08:36发布

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

8条回答
叼着烟拽天下
2楼-- · 2020-02-14 08:39

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);
}
查看更多
混吃等死
3楼-- · 2020-02-14 08:40

I recently wanted to determine approximately when there were NO MDIchildren open so I could display a panel with lots of "things to do" buttons on it Only when there were no child forms open. (just exploring a design idea).

My eventual solution was elegantly simple - add a timer to the parent form and start the timer up whenever the MdiChildActivate event determined there was 1 child form open.

    private void MyForm_MdiChildActivate(object sender, EventArgs e)
    {
        this.panel_Tools.Visible = false;
        if (this.MdiChildren.Count() == 1)
        {
            this.timer_WindowsCounter.Start();
        }
        else
        {
            this.timer_WindowsCounter.Stop();
        }

    }


    private void timer_WindowsCounter_Tick(object sender, EventArgs e)
    {
        if (this.MdiChildren.Count() == 0)
        {
            this.panel_Tools.Visible = true;
            this.timer_WindowsCounter.Stop();
        }
    }
查看更多
Ridiculous、
4楼-- · 2020-02-14 08:41

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.

查看更多
Juvenile、少年°
5楼-- · 2020-02-14 08:44
private void closeToolStripMenuItem1_Click(object sender, EventArgs e)
    {
      List<Form> fm = this.MdiChildren.ToList();
        if(fm!=null && fm.Count>0)
        {
            foreach(Form lfm in fm)
            {
                lfm.Close();
            }
        }
    }
查看更多
成全新的幸福
6楼-- · 2020-02-14 08:46

Since the MdiChildActivate event is fired before the MDI child form is actually closed and therefore there isn't enough information to detect if a MDI child form is actually activated or closed, I chose a different approach to solve the problem.

I found that the ParentChanged event fires on the MDI child form when it is closed.

public class MdiParentForm : Form
{
    // ...

    private Form CreateMdiChildForm()
    {
        var form = new MdiChildForm
        form.ParentChanged += MdiFormParentChangedHandler;
        form.MdiParent = this;
        return form;
    }

    private void MdiFormParentChangedHandler(object sender, EventArgs args)
    {
        var form = sender as Form;
        if (form != null)
        {
            if (form.MdiParent != null)
            {
                // MDI child form will activate
                // ... your code here
            }
            else
            {
                // MDI child form will close
                form.ParentChanged -= MdiFormParentChangedHandler;
                // ... your code here
            }
        }
    }

    // ...
}
查看更多
家丑人穷心不美
7楼-- · 2020-02-14 08:51

I realised this is many years too late however as the answers here helped me solve this I though I would mention this works fine using the MdiChildren array in .net 4. The only thing you need to do is check if the form is disposing or disposed to tell if its closing.

ie:

    private void frmContainer_MdiChildActivate(object sender, EventArgs e)
    {
        tabWindows.RefreshLayout(this.MdiChildren.ToList());
    }

    public void RefreshLayout(List<Form> forms)
    {
        this.nextButtonLeft = 1;
        panel1.Controls.Clear();
        foreach (Form frm in forms)
        {
            if (!(frm.Disposing || frm.IsDisposed)) { addButton(frm); }
        }
    }
查看更多
登录 后发表回答