MDI 子窗体作为对话框窗体(MDI 模态解决方法)






4.05/5 (13投票s)
是否曾经需要在一个特定窗体显示为对话框时,阻止所有其他窗体和控件?这是一个非常简单的规避方案,用于 MDI 模态窗体。
引言
是否曾经需要在一个特定窗体显示为对话框时,阻止所有其他窗体和控件?这是一个非常简单的规避方案,用于 MDI 模态窗体。
背景
我正在设计一个 MDI 丰富的应用程序,我需要一个对话框窗体只在父窗体中显示,并在用户在对话框窗体上选择内容之前阻止应用程序的其余部分。
使用代码
代码非常非常简单;只需在您的 MDI 父窗体上继承 MDIParent
窗体,而不是正常的窗体继承。
public partial class Your_MDI_Parent_Form : MdiParent
要将窗体显示为对话框并阻止其他控件,请在父窗体上调用 ShowChildDialog
方法,如下所示
ChildForm frm = new ChildForm();
ShowChildDialog(frm, ChildForm_DialogReturned);
并且,要接收来自子窗体的 DialogResult
,请使用以下事件接收器
private void ChildForm_DialogReturned(object sender, DialogResultArgs e)
{
MessageBox.Show("ChildForm returned: " + e.Result.ToString());
((Form)sender).Dispose();
}
代码解释
ShowChildDialog
方法
public void ShowChildDialog(Form frm,
EventHandler<DialogResultArgs> DialogReturnedValue)
{
frm.MdiParent = this;
frm.MaximizeBox = false;
frm.FormClosed += new FormClosedEventHandler(frm_FormClosed);
callingsender = frm;
DialogReturning += DialogReturnedValue;
DisableControls();
frm.Show();
}
- 设置 MDI 父窗体,以便窗体在父窗体中显示。
- 移除子窗体上的最大化按钮。
- 为子窗体的
Closed
事件添加一个事件接收器;这将用于从子对话框窗体返回对话框结果。 callingsender
用于内部使用,以便代码知道它正在处理哪个窗体。- 添加一个事件接收器来接收返回的对话框结果。
- 调用
DisableControls
方法将禁用MdiParent
中的所有其他控件和窗体。 - 最后,显示窗体。这将是唯一启用的窗体。
DisableControls
方法
private void DisableControls()
{
for (int i = 0; i < this.Controls.Count; i++)
{
if (this.Controls[i].GetType() != typeof(MdiClient))
this.Controls[i].Enabled = false;
}
foreach (Form frm in MdiChildren)
frm.Enabled = false;
if(callingsender != null)
callingsender.Enabled = true;
}
- 循环遍历 MDI 父窗体的所有控件,如果它不是 MDI 子控件,则禁用它们。
- 循环遍历所有子窗体并禁用它们。
- 如果
callingsender
不为null
,则再次启用它。
ForceReleaseOfControls
方法
public void ForceReleaseOfControls()
{
for (int i = 0; i < this.Controls.Count; i++)
this.Controls[i].Enabled = true;
foreach (Form frm in MdiChildren)
frm.Enabled = true;
}
- 循环遍历所有控件并再次启用它们。
- 循环遍历所有子窗体并再次启用它们。
代码不执行的操作...
此代码不会检查控件和窗体的预启用状态。因此,它不会记住控件/窗体在禁用之前是什么启用状态,并将其设置回该状态。可以通过使用键和值的集合来实现这一点。但目前,这就是代码。希望它能帮助那些遇到与我相同问题的人。
关注点
我学到了一些关于 MDI 应用程序的新知识。
历史
- 2009 年 12 月 21 日:首次发布。
- 2009 年 12 月 21 日(之后):更新文章,添加了一些代码解释。