【问题标题】:working with three winforms as mdi parent and child使用三个 Winform 作为 mdi 父级和子级
【发布时间】:2011-03-23 14:50:05
【问题描述】:

我有 3 个表格 - Form1,2,3。 Form1 是 MdiContainer。现在,当单击 Form1 上的按钮时,它会显示 Form2,而在 Form2 上,当单击按钮时,它会显示 Form3。我的代码如下,但它给出了 Form2 不是 MdiContainer 的错误。但是如果我将 Form2 设为 MdiContainer,那么它会给出 Form2 是 MdiChild 并且不能是 MdiContainer 的错误。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 f2 = new Form2();
        f2.Show();
        f2.MdiParent = this;
    }
}

public partial class Form2 : Form

{
    public Form2()
    {
        InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {

        Form3 f3 = new Form3();
        f3.Show();
        f3.MdiParent = this;
    }
}

如何做到这一点?

简而言之,我想要: Form2 的父级是 Form1,并且, Form3 的父级是 Form2

【问题讨论】:

标签: c# .net winforms parent-child mdi


【解决方案1】:

你不能。您只能有一个 MDI 父级。在该父容器中,您可以有许多子窗体,但这些窗体只能直接生成其他窗体,而不能作为 MDI 子窗体。

用微软自己的话来说:

多文档界面 (MDI) 的 Microsoft Windows 实现不支持嵌套的 MDI 客户端窗口。换句话说,MDI 客户端窗口和 MDI 子窗口都不能将 MDI 客户端窗口作为子窗口。

【讨论】:

    【解决方案2】:

    因为 Form2 不是 MDI 容器,所以它不起作用。

    【讨论】:

      【解决方案3】:

      基本上不支持此功能,但是您可以通过其他方式复制它。您希望 f2 成为 f3 的父级仅仅是为了视觉表示吗?我试图理解以便给你一个正确的答案。那么你想完成什么?如果您希望 f3 嵌入到 f2 上,您可以创建一个用户控件并将其作为控件添加到您的表单中。

      如果你想让 f3 弹出你可以使用

      f3.showdialog();
      

      如果您这样做,请不要指定 f3 的 mdiparent。

      埃里克

      【讨论】:

      • 其实是在开发一个软件,所以我必须这样做。有没有其他方法可以完成这个任务,我的意思是没有MDI,如何使用winforms构建软件?
      • 另外,如果我使用 ShowDialog(),那么当 Form3 显示时,Form1 也会被禁用。我希望 Form1 始终处于启用状态,与任何否无关。我打开了更多表格。
      • 你可以使用'f3.show();'没有'f3.mdiparent = this;'相比之下,您可以设置 'f3.mdiparent = f1;'为什么要 f2 成为 f3 的父级?
      • @sqlchild:根据您所说的,我可能会采用 Dorababu 的方法并使 f3 = f1; 的 mdiparent;
      【解决方案4】:

      我尝试如下写出

       f2.MdiParent = this;
      

      代码有效

      如果你想不使用 showdialog 意味着在 Button_click 上写以下内容

      bool IsOpen = false;
      foreach (Form f in Application.OpenForms)
      {
          if (f.Text == "Form2") //  Name of the Form
          {
              IsOpen = true;
              f.Focus();
              break;
          }
      }
      if (IsOpen == false)
      {
          Form2 f2 = new Form2();
         //f2.MdiParent = this;
          f2.Show();
      }
      

      【讨论】:

      • 没有 Form.showdialog() 我们可以阻止表单多次加载
      【解决方案5】:

      一个应用程序中只有一个 MdiContainer,其他的应该是子窗体。

      但是,您可以通过 ShowDialog 而不是 Show() 大致实现您的功能

      private void button1_Click(object sender, EventArgs e)
      {
          Form3 f3 = new Form3();
          f3.ShowDialog();
      }
      

      编辑 1 由于您的 cmets,@Dorababu 提供的解决方案最适合您,并进行了一些改进;将form1 设为form3 的父级。所以你的form3会显示在MdiParent里面。

      private void button1_Click(object sender, EventArgs e)
      {
          Form3 f3 = new Form3();
         //f3.MdiParent = this;
          // instead use this.MdiParent
          f3.MdiParent = this.MdiParent;
          f2.Show();
      }
      

      如果显示form3,则检查form2的get focus事件,然后将焦点设置为form3,因此在打开form3之前,form2不会获得焦点。

      private void Form2_Activated(object sender, EventArgs e)
      {
          // inside Focus event of Form2
          foreach (Form f in Application.OpenForms)
          {
              if (f.Text == "Form3") //  Name of the Form
              {
                  f.Focus();
                  break;
              }
          }
      }
      

      【讨论】:

      • 如果我这样做,那么当 Form3 显示时,Form1 也会被禁用。我希望 Form1 始终处于启用状态,与任何否无关。我打开了更多表格。
      • @sqlchild,@Dorababu 的解决方案最好进行一些修改。
      猜你喜欢
      • 2017-04-25
      • 1970-01-01
      • 2013-08-27
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 1970-01-01
      • 2017-02-18
      • 1970-01-01
      相关资源
      最近更新 更多