You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 20:40:10