65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.05/5 (13投票s)

2009年12月21日

CPOL

2分钟阅读

viewsIcon

89916

downloadIcon

3488

是否曾经需要在一个特定窗体显示为对话框时,阻止所有其他窗体和控件?这是一个非常简单的规避方案,用于 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();
}
  1. 设置 MDI 父窗体,以便窗体在父窗体中显示。
  2. 移除子窗体上的最大化按钮。
  3. 为子窗体的 Closed 事件添加一个事件接收器;这将用于从子对话框窗体返回对话框结果。
  4. callingsender 用于内部使用,以便代码知道它正在处理哪个窗体。
  5. 添加一个事件接收器来接收返回的对话框结果。
  6. 调用 DisableControls 方法将禁用 MdiParent 中的所有其他控件和窗体。
  7. 最后,显示窗体。这将是唯一启用的窗体。

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;
}
  1. 循环遍历 MDI 父窗体的所有控件,如果它不是 MDI 子控件,则禁用它们。
  2. 循环遍历所有子窗体并禁用它们。
  3. 如果 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;
}
  1. 循环遍历所有控件并再次启用它们。
  2. 循环遍历所有子窗体并再次启用它们。

代码不执行的操作...

此代码不会检查控件和窗体的预启用状态。因此,它不会记住控件/窗体在禁用之前是什么启用状态,并将其设置回该状态。可以通过使用键和值的集合来实现这一点。但目前,这就是代码。希望它能帮助那些遇到与我相同问题的人。

关注点

我学到了一些关于 MDI 应用程序的新知识。

历史

  • 2009 年 12 月 21 日:首次发布。
  • 2009 年 12 月 21 日(之后):更新文章,添加了一些代码解释。
© . All rights reserved.