C# MDI 多文档窗体(父子窗体、布局平铺、单例显示)全套笔记 一、MDI 核心概念1. 什么是 MDIMDI多文档界面一个主窗体中可以嵌套多个子窗体所有子窗体只能在主窗体内部显示不会独立弹出悬浮窗口。常见软件场景Word、Excel、PS 多文档窗口。2. 核心属性与方法窗体.IsMdiContainer true设置当前窗体为MDI父容器必须手动勾选/设置子窗体.MdiParent this指定子窗体的所属父窗体this.MdiChildren获取当前父窗体所有已打开的子窗体集合LayoutMdi()批量排布子窗体布局二、MDI 三种经典布局枚举布局枚举效果MdiLayout.TileVertical垂直平铺左右均分MdiLayout.TileHorizontal水平平铺上下均分MdiLayout.Cascade层叠平铺堆叠窗口三、基础功能打开多个子窗体 自动布局一次性打开 Form2、Form3并设置垂直平铺布局private void 打开窗体ToolStripMenuItem_Click(object sender, EventArgs e) { // 打开子窗体2并绑定父容器 Form2 f2 new Form2(); f2.MdiParent this; f2.Show(); // 打开子窗体3修改背景色并绑定父容器 Form3 f3 new Form3(); f3.MdiParent this; f3.BackColor Color.Red; f3.Show(); // 所有子窗体 垂直平铺 LayoutMdi(MdiLayout.TileVertical); }四、布局切换功能private void 设置窗体ToolStripMenuItem_Click(object sender, EventArgs e) { // 切换为水平平铺 LayoutMdi(MdiLayout.TileHorizontal); }五、核心重难点通用 Open 方法子窗体单例逻辑1. 功能需求重复点击菜单不会重复创建同类型窗体如果当前已经打开该类型窗体隐藏所有窗体、激活并显示原有窗体如果是新类型窗体隐藏所有旧窗体、展示新窗体实现始终只显示一个子窗体的效果2. 完整核心源码/// summary /// MDI子窗体通用打开方法去重单例切换逻辑 /// /summary public void Open(Form f) { // 1. 遍历所有已打开的MDI子窗体 foreach (var item in this.MdiChildren) { // 判断即将打开的窗体类型 已存在的子窗体类型 if (f.GetType() item.GetType()) { // 隐藏所有子窗体 foreach (Form child in this.MdiChildren) { child.Hide(); } // 显示并激活当前已有窗体不重复new item.Show(); item.Activate(); return; } } // 2. 走到这里说明当前没有同类型窗体 // 隐藏所有旧窗体 foreach (Form child in this.MdiChildren) { child.Hide(); } // 绑定父容器并展示新窗体 f.MdiParent this; f.Show(); }3. 逻辑拆解GetType() 类型对比判断窗体是否为同一个窗体类解决重复实例化问题存在同类型窗体全部隐藏 → 激活旧窗体 → return 终止方法不创建新对象不存在同类型窗体隐藏所有旧窗体 → 创建并展示新窗体六、菜单调用封装方法// 打开Form2单例 private void 打开窗体1ToolStripMenuItem_Click(object sender, EventArgs e) { Open(new Form2()); } // 打开Form3单例 private void 打开窗体2ToolStripMenuItem_Click(object sender, EventArgs e) { Open(new Form3()); }七、MDI 两套写法对比写法一基础版每次点击都 new 新窗体会出现多个同类型子窗体叠加写法二进阶封装版通过类型判断 隐藏激活保证同类窗体永远唯一企业项目标准写法八、高频易错点主窗体必须开启IsMdiContainer true否则无法嵌套子窗体必须赋值MdiParent this否则窗体独立弹出不属于子窗体 对比窗体对象会一直创建新窗体必须用GetType() 对比类型不写 return 会继续执行创建新窗体无法实现单例MdiChildren 只能获取当前存活、已加载的子窗体九、MDI 背诵口诀主窗开启容器态子窗绑定父窗体MdiChildren遍历子类型判断去重替先藏后显保唯一布局平铺横竖齐封装通用Open法多文档界面稳如一。