是否有一个事件可以用来判断子窗体是否已从 MDI 父窗体中添加或删除?
8 回答
是的。在您的主 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();
}
}
当子窗体被激活或停用时,该事件将触发。
将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);
}
不,那里没有。您必须继承 Form 并公开特定事件,这些事件将指示何时添加子表单,然后通过连接子表单的方法路由子表单的所有附件,并引发事件。
我意识到这已经晚了很多年,但是因为这里的答案帮助我解决了这个问题,但我会提到使用 .net 4 中的 MdiChildren 数组可以正常工作。您唯一需要做的就是检查表单是否正在处理或处理告诉它是否关闭。
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); }
}
}
是的,您可以轻松检测添加到 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 表单中删除的子表单。
希望这会帮助你。
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();
}
}
}
由于 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
}
}
}
// ...
}
我最近想确定大约什么时候没有打开 MDIchildren,这样我就可以显示一个面板,上面有很多“要做的事情”按钮只有当没有打开子窗体时。(只是探索一个设计理念)。
我的最终解决方案非常简单——在父表单中添加一个计时器,并在 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();
}
}