添加或删除使用子表单检测的MDI表单

时间:2009-02-11 18:45:32

标签: c# winforms .net-3.5 mdi

是否有可用于判断是否已从MDI父级添加或删除子表单的事件?

8 个答案:

答案 0 :(得分:7)

是。在主MDI表单上,连接到MdiChildActivated事件。

像这样:

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();
        }
    }

当子表单被激活或停用时,该事件将触发。

答案 1 :(得分:4)

连接MdiChildActivate事件并保留已识别的孩子列表。激活新表单时,还会连接FormClosed事件。

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);
}

答案 2 :(得分:2)

不,没有。您必须子类化Form并公开指示何时添加子项的特定事件,然后通过一种方法路由子表单的所有附件,以及引发子表单。

答案 3 :(得分:1)

我意识到这已经太晚了,但是因为这里的答案帮助我解决了这个问题,但是我会提到使用.net 4中的MdiChildren数组工作正常。你唯一需要做的就是检查表格是否是处置或处置以判断其是否已关闭。

即:

    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); }
        }
    }

答案 4 :(得分:1)

是的,您可以轻松检测以MDI表格添加的表单。

通过将IsMdiContainer设置为true将 ParentForm标记为MdiContainer 时,会引发 ParentForm.ControlAdded 事件,以将“MdiClient”控件添加到父窗体。因此,当将MdiClient添加到父MDI表单时,我们可以为MdiClient控件引发ControlAdded事件,如下所示,

  public ParentForm()
  {
    InitializeComponent();
    this.ControlAdded += Form1_ControlAdded;
    this.IsMdiContainer = true;

我们需要像下面一样提高MdiClient.ControlAdded,

    void Form1_ControlAdded(object sender, ControlEventArgs e)
      {
           if(e.Control is MdiClient)
                e.Control.ControlAdded += MdiClient_ControlAdded;

      }

默认情况下, MDI子窗体将以父窗体的形式添加到MdiClient 的控件集合中。因此,当将ChildForm.MdiParent值设置为Parent表单时,MdiClient的 ControlAdded事件将引发

void MdiClient_ControlAdded(object sender, ControlEventArgs e)
{

}

因此,通过使用上述方法,您可以知道添加到父MDI表单中的子MDI表单。像这样,您可以为MdiClient控件添加ControlRemoved事件,以了解从MDI表单中删除的子表单。

希望这会对你有所帮助。

答案 5 :(得分:0)

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 :(得分:0)

由于在MDI子窗体实际关闭之前触发了MdiChildActivate事件,因此没有足够的信息来检测MDI子窗体是否实际被激活或关闭,我选择了不同的方法来解决问题。

我发现ParentChanged事件在MDI子窗体关闭时触发。

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 :(得分:-2)

我最近想确定什么时候没有MDIchildren打开,所以我可以显示一个有很多&#34;要做的事情的面板&#34;它上面的按钮只有当没有打开子窗体时。 (只是探索一个设计理念)。

我的最终解决方案非常简单 - 只要MdiChildActivate事件确定有1个子窗体打开,就可以向父窗体添加一个计时器并启动计时器。

    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();
        }
    }