如何在基窗体FormBase中获取继承窗体的尺寸?
Oh I get this issue—when you move that AddToFormSizes call to the base form's constructor, you're hitting a classic constructor execution order problem. Let me break it down and show you how to fix it.
Why This Happens
Here's the order of operations when you create an instance of formTest:
- The
FormBaseconstructor runs first. - Then
formTest's constructor runs, including itsInitializeComponent()method where the subclass's actual size is set.
So when FormBase calls AddToFormSizes in its constructor, the subclass hasn't had a chance to set its own size yet—you're just getting the base form's design-time size instead.
Solutions That Work
1. Use the Form's Load Event (Simple & Reliable)
The Load event fires after all initialization is done, including the subclass's InitializeComponent. You can hook this event in your base form to capture the correct size:
public class FormBase : Form { public FormBase() { InitializeComponent(); // Subscribe to the Load event Load += OnFormBaseLoaded; } private void OnFormBaseLoaded(object sender, EventArgs e) { // Now we have the subclass's actual size Program.MainForm.AddToFormSizes(this, Size); // Optional: Unsubscribe to avoid redundant calls if the form loads again Load -= OnFormBaseLoaded; } }
2. Override OnLoad (More "WinForms-idiomatic")
Instead of subscribing to an event, you can override the form's virtual OnLoad method—this is the preferred way to extend form behavior in WinForms:
public class FormBase : Form { public FormBase() { InitializeComponent(); } protected override void OnLoad(EventArgs e) { // Always call the base method first to preserve default behavior base.OnLoad(e); // Now capture the correct size Program.MainForm.AddToFormSizes(this, Size); } }
3. (Alternative) Have Subclasses Call a Base Method (Less Ideal)
If for some reason you need something closer to constructor timing, you can create a protected method in the base form and have subclasses call it after their InitializeComponent. But this requires all subclasses to remember to do this, so it's not as clean as the first two options:
// FormBase public class FormBase : Form { public FormBase() { InitializeComponent(); } protected void RegisterFormSize() { Program.MainForm.AddToFormSizes(this, Size); } } // Subclass example public class formTest : FormBase { public formTest() { InitializeComponent(); // Call the base method after our own initialization RegisterFormSize(); } }
Bonus Note
If you ever need to track size changes after the form is loaded (not just the initial size), you could hook into the SizeChanged event in the base form and update the dictionary there too. But for your current use case of storing the initial size, Load or OnLoad is perfect.
内容的提问来源于stack exchange,提问作者GuidoG

