假设你有一个名为FormBase
的表单,所有其他表单都继承自该表单。
例如,我有public class Form formTest : FormBase
我现在在表单测试的 ctor 中拥有什么:
public class Form formTest : FormBase
{
public formTest()
{
InitializeComponent();
Program.MainForm.AddToFormSizes(this, this.Size);
}
}
此代码将formTest
的实例添加到主窗体上的字典中,并size
这有效,但我想将此代码移动到FormBase
这样我就不必将这行代码都放在每个继承的形式中。
public class Form FormBase : Form
{
public FormBase()
{
InitializeComponent();
Program.MainForm.AddToFormSizes(this, this.Size);
}
}
现在,问题是,当我这样做时,size
在设计时的大小为FormBase
,而不是formTest
的大小。
有没有办法在FormBase
捕获formTest
的大小或从FormBase
继承的任何其他形式?
作为参考,这是 MainForm 中的AddToFormSizes
代码
private Dictionary<Form, Size> _formSizes = new Dictionary<Form, Size>();
public void AddToFormSizes(Form form, Size size)
{
_formSizes.Add(form, form.Size);
}
问题:
使用Form
作为其他窗体的基础,在基类构造函数中,this
引用返回基类的Size
,而不是派生类的Size
。
public class FormBase : Form
{
public FormBase()
{
InitializeComponent();
Program.MainForm.AddToFormSizes(this, this.Size);
}
}
这只是遵循事件顺序的问题:
FormDerived derived = new FormDerived()
=> FormBase.InitializeComponent()
=> FormDerived.InitializeComponent()
derived.Show()
=> FormBase.OnHandleCreated()
给定从FormBase
派生的表单的构造函数:
public class FormDerived : FormBase
{
public FormDerived() => InitializeComponents();
}
首次创建类时:
FormDerived derived = new FormDerived();
derived.Show();
基类(FormBase
)的构造函数首先被调用。
此时,this
引用设置为FormDerived
,但所有属性(包括Name
和窗体的标题 (Text
)都设置为基类的值。
因此,调用在基类构造函数中使用this
的方法:
Program.MainForm.AddToFormSizes(this, this.Size);
this.Size
将返回基类的大小,而不是派生类。
接下来调用FormDerived
构造函数。此时,将设置InitializeComponent()
方法中定义的所有属性。
如果将AddToFormSizes()
方法移动到派生类构造函数,this
将引用预期的值。但是,静态方法调用必须插入到每个派生类中FormBase
。
可以改为将AddToFormSizes()
方法移动到基类的重写OnHandleCreated()
方法并从中调用,该方法将在首次显示派生窗体时调用:
derived.Show();
将导致调用FormBase.OnHandleCreated()
。
此时,this
引用已设置为派生类,InitializeComponent()
中定义的所有属性都将已设置为派生类的值。Name
,当然包括Text
和Size
。
在这里,this
FormDerived
其构造函数中设置的所有属性:
public class FormBase : Form
{
public FormBase() => InitializeComponent();
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
Program.MainForm.AddToFormSizes(this, this.Size);
}
}