winforms MDI窗体检测是否添加或删除了子窗体

hrirmatl  于 2022-11-17  发布在  其他
关注(0)|答案(9)|浏览(208)

是否有事件可用来告知子表单是否已从MDI父表单中加入或移除?

mzmfm0qo

mzmfm0qo1#

是。在主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();
        }
    }

并且该事件将在激活或停用子窗体时激发。

gmol1639

gmol16392#

连接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);
}
omtl5h9j

omtl5h9j3#

不,没有。您必须建立Form的子类别(Subclass),并公开特定的事件,以指出子表单何时加入,然后透过连接子表单的方法来传送子表单的所有附件,并引发事件。

1wnzp6jl

1wnzp6jl4#

我意识到这已经晚了很多年,但是,由于这里的答案帮助我解决了这个问题,我想我会提到,使用.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); }
        }
    }
r55awzrz

r55awzrz5#

是的,你可以很容易地检测到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值设置为父窗体时,MdiClient的ControlAdded事件将引发

void MdiClient_ControlAdded(object sender, ControlEventArgs e)
{

}

因此,通过使用上述方法,您可以了解添加到父MDI窗体中的子MDI窗体。类似地,您可以为MdiClient控件添加ControlRemoved事件,以了解从MDI窗体中删除的子窗体。
希望这对你有帮助。

cnjp1d6j

cnjp1d6j6#

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

ztyzrc3y7#

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

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

    // ...
}
4xrmg8kj

4xrmg8kj8#

我有你的答案:D
首先检测到新的MdiChild处于活动状态,然后:

private void Form1_MdiChildActivate(object sender, EventArgs e)
{
    //form is new mdi child
    Form form = this.MdiChildren.Last();
    form.FormClosed += SenderForm_Close;
}

private void SenderForm_Close(object sender, EventArgs e)
{
    //form is new closed mdi child
    Form form = sender as Form;
}
dced5bon

dced5bon9#

我最近想确定大约什么时候没有打开MDI子窗体,以便只有在没有打开子窗体的情况下才能显示一个面板,上面有许多“要做的事情”按钮。(只是探索一个设计思想)。
我最终的解决方案非常简单--向父窗体添加一个计时器,并在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();
        }
    }

相关问题