一、什么是窗体继承
窗体继承 = 把一个基础窗体(父窗体) 作为模板,其他窗体(子窗体)直接继承它,复用界面、控件、事件、代码,不用重复写相同布局逻辑。 适用场景:系统统一头部、统一按钮、统一弹窗样式、统一校验逻辑。
二、两种继承方式
1. 可视化继承(最常用,设计器可见)
-
新建父窗体
BaseForm放通用控件:标题栏、退出按钮、底部状态栏、统一样式、通用方法。// BaseForm.cs 父窗体
using System;
using System.Windows.Forms;namespace WinFormDemo
{
public partial class BaseForm : Form
{
public BaseForm()
{
InitializeComponent();
// 统一窗体基础设置
this.StartPosition = FormStartPosition.CenterScreen;
this.Font = new System.Drawing.Font("微软雅黑", 9);
}// 通用关闭方法,所有子窗体都能用 protected void BtnClose_Click(object sender, EventArgs e) { this.Close(); } // 通用弹窗提示 protected void ShowMsg(string msg) { MessageBox.Show(msg, "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } }}
-
创建子窗体,修改继承关系 新建窗体默认是
: Form,改成继承父窗体: BaseForm// ChildForm.cs 子窗体
namespace WinFormDemo
{
public partial class ChildForm : BaseForm // 继承自定义窗体,不是Form
{
public ChildForm()
{
InitializeComponent();
}private void button1_Click(object sender, EventArgs e) { // 直接调用父窗体protected方法 ShowMsg("子窗体调用父类提示"); } }}
-
设计器效果 打开
ChildForm设计界面,会自动加载父窗体所有控件、布局,可新增自有控件,不能删除父窗体控件(只读)。
2. 代码式继承(无可视化,纯逻辑复用)
只写父类逻辑,不放控件,仅复用公共方法、字段,适合工具类基窗。
三、访问修饰符关键规则(重点)
表格
| 修饰符 | 子类能否访问父窗体控件 / 方法 | 设计器能否修改父控件 |
|---|---|---|
private |
不能 | 不可见 |
protected |
可以 | 可见但不能删除 |
public |
可以 | 可见、可修改属性 |
实操建议:
- 通用按钮、事件方法写
protected,子类可直接调用; - 父窗体控件默认
private,子类无法直接操作,如需修改:- 把控件 Modifiers 属性改为
protected; - 或写
public封装方法给子类调用。
- 把控件 Modifiers 属性改为
示例:父窗体有 label 标题,子类修改文字
csharp
运行
// BaseForm 封装接口
public void SetTitle(string text)
{
lblTitle.Text = text;
}
// 子窗体调用
public ChildForm()
{
InitializeComponent();
SetTitle("学生管理页面");
}
四、多级继承
父窗体 → 一级子窗体 → 二级子窗体,层层复用:
plaintext
BaseForm(底层通用)
└── AdminBaseForm(管理员专用基窗)
└── StudentForm(学生管理窗口)
五、常见问题
-
子类无法删除父窗体控件 设计器中父窗体生成的控件灰色只读,只能隐藏:
control.Visible = false。 -
父窗体构造函数自动执行 子类实例化时,先执行父类无参构造,再执行子类构造; 若父窗体只有带参构造,子类必须显式调用:
public ChildForm(string title) : base(title) { InitializeComponent(); } -
父窗体事件被子类重写 父方法加
virtual,子类用override重写:// 父类 protected virtual void LoadForm() { ShowMsg("父窗体加载"); } // 子类重写 protected override void LoadForm() { base.LoadForm(); // 可选:执行父类原有逻辑 ShowMsg("子类扩展加载逻辑"); } -
跨项目继承注意 父窗体项目要生成 dll,子项目引用该 dll,才能可视化继承。
六、完整使用流程总结
- 创建基础窗体
BaseForm,封装统一 UI、通用方法; - 把控件、工具方法设为
protected供子类调用; - 新建业务窗体,修改继承为
: BaseForm; - 子窗体新增专属控件、重写虚方法扩展业务;
- 实例化子窗体,自动拥有父窗体全部能力。
七、优势
- 统一系统 UI 风格,不用每个窗体重复布局;
- 公共逻辑只写一次,后期修改只改父窗体全部生效;
- 减少代码冗余,便于维护、统一迭代。