如何获取基本表单中继承表单的大小?

Gui*_*doG 3 c# visual-inheritance winforms

假设您有一个名为 的表单FormBase,并且所有其他表单都继承自该表单。
例如,我有public class Form formTest : FormBase

我现在在 formTest 的 ctor 中拥有什么:

public class Form formTest : FormBase
{
    public formTest()
    {
        InitializeComponent();
        Program.MainForm.AddToFormSizes(this, this.Size);
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码将 的实例添加formTest到主窗体上的字典中,其名称为size

这可行,但我想将此代码移至,FormBase这样我就不必将这行代码放入每个继承的表单中。

public class Form FormBase : Form
{
    public FormBase()
    {
        InitializeComponent();
        Program.MainForm.AddToFormSizes(this, this.Size);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在的问题是,当我这样做时,size将在设计时获得 的大小FormBase,而不是 的大小formTest

有没有办法FormBase捕获 的大小formTest或继承自 的任何其他形式FormBase

AddToFormSizes作为参考,这是MainForm 中的代码

private Dictionary<Form, Size> _formSizes = new Dictionary<Form, Size>();
public void AddToFormSizes(Form form, Size size)
{
    _formSizes.Add(form, form.Size);
}
Run Code Online (Sandbox Code Playgroud)

Jim*_*imi 5

问题
使用 aForm作为其他窗体的基类,在基类构造函数中,this引用返回Size基类的 ,而不是Size派生类的 。

public class FormBase : Form
{
    public FormBase()
    {
        InitializeComponent();
        Program.MainForm.AddToFormSizes(this, this.Size);
    }
}
Run Code Online (Sandbox Code Playgroud)

只需遵循事件的顺序即可:

FormDerived derived = new FormDerived()
=> FormBase.InitializeComponent()
=> FormDerived.InitializeComponent()
derived.Show()
=> FormBase.OnHandleCreated()
Run Code Online (Sandbox Code Playgroud)

给定一个 Form 的构造函数,派生自FormBase

public class FormDerived : FormBase
{
     public FormDerived() => InitializeComponents();    
}
Run Code Online (Sandbox Code Playgroud)

当类第一次创建时:

FormDerived derived = new FormDerived();
derived.Show();
Run Code Online (Sandbox Code Playgroud)

FormBase首先调用基类 ( ) 的构造函数。
此时,this引用设置为FormDerived,但所有属性,包括Name和表单的标题 ( Text),都设置为基类的值。因此,调用在基类构造函数中
使用的方法:this

Program.MainForm.AddToFormSizes(this, this.Size);
Run Code Online (Sandbox Code Playgroud)

this.Size将返回基类的 Size,而不是派生类的 Size。

FormDerived接下来调用构造函数。此时,该InitializeComponent()方法中定义的所有属性都将被设置。

如果将该AddToFormSizes()方法移至派生类构造函数,this将引用预期值。但是,静态方法调用必须插入到 的每个派生类中FormBase

AddToFormSizes()方法可以移至OnHandleCreated()基类的重写方法并从中调用,该方法将在派生 Form 首次显示时调用:

derived.Show();
Run Code Online (Sandbox Code Playgroud)

将引起对 的调用FormBase.OnHandleCreated()

此时,this引用已设置为派生类,并且 中定义的所有属性 InitializeComponent()也已设置为派生类的值。
Name,当然 Text也包括在内。Size

这里thisFormDerived在其构造函数中设置的所有属性:

public class FormBase : Form
{
    public FormBase() => InitializeComponent();

    protected override void OnHandleCreated(EventArgs e)
    {
         base.OnHandleCreated(e);
         Program.MainForm.AddToFormSizes(this, this.Size);
    }
}
Run Code Online (Sandbox Code Playgroud)