Skip to content

WinForm-如何在窗体中显示窗体

在 WinForm 中,要在窗体 Form 中显示另一个窗体 Form,通常有两种主要方法:

1. 将一个 Form 作为另一个 Form 的子窗体(MDI 子窗体)

这种方法适用于创建多文档界面 (MDI) 应用程序,其中一个父窗体包含多个子窗体,子窗体在父窗体的范围内移动和操作。

  • 设置父窗体的 IsMdiContainer 属性: 将父窗体的 IsMdiContainer 属性设置为 true。这将使父窗体成为 MDI 容器。

    csharp
    this.IsMdiContainer = true; // 在父窗体的构造函数或 Load 事件中
  • 设置子窗体的 MdiParent 属性: 将要显示的子窗体的 MdiParent 属性设置为父窗体。

    csharp
    Form2 childForm = new Form2();
    childForm.MdiParent = this; // this 指的是父窗体
    childForm.Show();
  • 示例代码:

    csharp
    public partial class Form1 : Form // 父窗体
    {
        public Form1()
        {
            InitializeComponent();
            this.IsMdiContainer = true;
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            Form2 childForm = new Form2();
            childForm.MdiParent = this;
            childForm.Show();
        }
    }
    
    public partial class Form2 : Form // 子窗体
    {
        public Form2()
        {
            InitializeComponent();
        }
    }
  • 优点: 方便管理多个子窗体,子窗体只能在父窗体内移动。

  • 缺点: 限制了子窗体的显示范围,不够灵活。

2. 将一个 Form 作为控件添加到另一个 Form 中(非 MDI 方式)

这种方法更灵活,可以将一个 Form 嵌入到另一个 Form 的某个区域,就像添加其他控件一样。

  • 设置子窗体的 TopLevel 属性: 将子窗体的 TopLevel 属性设置为 false。这是关键步骤,使子窗体表现得像一个控件。

  • 设置子窗体的 Parent 属性: 将子窗体的 Parent 属性设置为要添加到的父窗体上的某个控件(例如 Panel、GroupBox 等)。

  • 设置子窗体的 FormBorderStyle 属性: 通常需要将子窗体的 FormBorderStyle 属性设置为 None,以去除子窗体的边框和标题栏,使其更好地融入父窗体。

  • 示例代码:

    csharp
    public partial class Form1 : Form // 父窗体
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            Form2 childForm = new Form2();
            childForm.TopLevel = false;
            childForm.FormBorderStyle = FormBorderStyle.None; // 可选,去除边框
            childForm.Parent = panel1; // panel1 是父窗体上的一个 Panel 控件
            childForm.Dock = DockStyle.Fill; // 可选,使子窗体填充 Panel
            childForm.Show();
        }
    }
    
    public partial class Form2 : Form // 子窗体
    {
        public Form2()
        {
            InitializeComponent();
        }
    }
  • 优点: 更加灵活,可以自由控制子窗体的位置和大小。

  • 缺点: 需要手动管理子窗体的生命周期和布局。

3. 关键点总结

  • MDI 子窗体: IsMdiContainerMdiParent 属性。
  • 非 MDI 子窗体: TopLevel = falseParent 属性,通常还需要设置 FormBorderStyle = FormBorderStyle.NoneDock 属性。

其他注意事项

  • 子窗体的初始化: 确保在显示子窗体之前正确初始化其控件和数据。
  • 子窗体的事件: 注意处理子窗体和父窗体之间的事件交互。
  • 资源管理: 及时释放不再使用的子窗体资源,避免内存泄漏。

推荐选择第二种方式。