如何在C# Windows Forms多窗体的Load事件中统一添加代码?
解决WinForms基窗体统一处理子窗体位置恢复(避免逐个修改子窗体)
方案1:重写基窗体的OnLoad虚方法(推荐)
WinForms窗体的Load事件由OnLoad虚方法触发,直接在基类FormX中重写该方法,所有继承自它的子窗体都会自动执行基类逻辑,无需逐个修改子窗体。
代码示例:
public class FormX : Form { protected override void OnLoad(EventArgs e) { // 先执行基类原有逻辑,保证窗体初始化流程正常 base.OnLoad(e); // 执行位置恢复逻辑 RestoreWindowPosition(); } private void RestoreWindowPosition() { // 从配置读取保存的位置、尺寸、窗口状态 if (Properties.Settings.Default.WindowPositions.TryGetValue(this.Name, out var pos)) { this.Location = pos.Location; this.Size = pos.Size; this.WindowState = pos.WindowState; } } // 保留原有关闭时的保存逻辑 protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); SaveWindowPosition(); } private void SaveWindowPosition() { // 保存当前窗体状态(注意处理最大化/最小化时的恢复边界) var pos = new WindowPosition { Location = this.WindowState == FormWindowState.Normal ? this.Location : this.RestoreBounds.Location, Size = this.WindowState == FormWindowState.Normal ? this.Size : this.RestoreBounds.Size, WindowState = this.WindowState }; Properties.Settings.Default.WindowPositions[this.Name] = pos; Properties.Settings.Default.Save(); } }
注意事项:
- 若某个子窗体自行重写了
OnLoad方法,必须确保它调用了base.OnLoad(e),否则基类的位置恢复逻辑不会执行。 - 处理最大化/最小化状态时,要使用
RestoreBounds获取窗体正常状态下的位置和尺寸,避免保存异常值。
方案2:在基窗体构造函数中订阅Load事件
如果不想修改虚方法,可在基类构造函数中直接订阅自身的Load事件,子类继承后会自动继承该事件订阅。
代码示例:
public class FormX : Form { public FormX() { InitializeComponent(); // 绑定Load事件 this.Load += FormX_Load; } private void FormX_Load(object sender, EventArgs e) { RestoreWindowPosition(); } // 保存位置的逻辑同方案1 }
该方案无需担心子类重写OnLoad的覆盖问题(除非子类手动取消订阅Load事件,这种情况极少),但虚方法的实现更符合WinForms的设计模式。
额外优化:彻底消除闪烁
若恢复位置后仍有轻微闪烁,可在基窗体构造函数中设置StartPosition为Manual,让窗体初始化时直接使用你指定的位置,跳过设计时默认位置的加载:
public FormX() { InitializeComponent(); this.StartPosition = FormStartPosition.Manual; }
内容的提问来源于stack exchange,提问作者Syed Irfan Ahmad
相关产品推荐
相关产品推荐

