Problem:
Using a Form
as base for other Forms, in the base class constructor, the this
reference returns the Size
of the base class instead of the Size
of the derived class.
public class FormBase : Form
{
public FormBase()
{
InitializeComponent();
Program.MainForm.AddToFormSizes(this, this.Size);
}
}
It's just a matter of following the sequence of events:
FormDerived derived = new FormDerived()
=> FormBase.InitializeComponent()
=> FormDerived.InitializeComponent()
derived.Show()
=> FormBase.OnHandleCreated()
Given the constructor of a Form derived from FormBase
:
public class FormDerived : FormBase
{
public FormDerived() => InitializeComponents();
}
when the class is first created:
FormDerived derived = new FormDerived();
derived.Show();
the constructor of the base class (FormBase
) is called first.
At this point, the this
reference is set to FormDerived
, but all the properties, including the Name
and the Form's Caption (Text
), are set to the values of the base class.
Hence, calling a method that uses this
in the base class constructor:
Program.MainForm.AddToFormSizes(this, this.Size);
this.Size
will return the Size of the base class, not the derived class.
The FormDerived
constructor is called next. At this point, all the properties defined in the InitializeComponent()
method will be set.
If the AddToFormSizes()
method is moved to the derived class constructor, this
will reference the expected values. But, the static method call must be inserted in each derived class of FormBase
.
The AddToFormSizes()
method can be instead moved to and called from the overridden OnHandleCreated()
method of the base class, which will be called when the derived Form is first shown:
derived.Show();
will cause a call to FormBase.OnHandleCreated()
.
At this point, the this
reference is already set to the derived class and all the properties defined in InitializeComponent()
will be already set to the values of the derived class.
Name
, Text
and Size
included, of course.
Here, this
is FormDerived
with all the properties set in its constructor:
public class FormBase : Form
{
public FormBase() => InitializeComponent();
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
Program.MainForm.AddToFormSizes(this, this.Size);
}
}