Problems with anchors and visual control inheritance

I have just spent a couple days playing around with the UI designer in Visual Studio. Now, there is an argument to be made for a UI framework that provides all the common controls and a few layout managers without involving any sort of visual designer tool. But when you’re working in .NET already and all you need is a quick and dirty mock-up of a dialog, it’s hard to beat the Designer. So, I have a form that I use a base for my dialogs. It looks roughly like this:
Base Form A panel for a header, a panel for a footer, and a button nested within the bottom panel. Pretty typical stuff that saves me a lot of time on each of the mock forms, since I don’t have to repeat the same steps every time. The bottom panel is docked to the bottom of the form and the button is anchored to Right and Bottom. When the button’s accessibility modifier in the base form is “private”, everything is groovy. But I want to be able to change the button’s text in the child dialogs, so I make the button “protected” instead. One size doesn’t fit all where forms and dialogs are concerned, so I resize my child forms and observe something that seems very strange — the inherited button moves outside the boundaries of the child form. Child Form (Broken)

Why does this happen?

When the button in the base form is protected and the child form is resized, the designer.cs file of the child form stores the new location of the button:

this.button1.Location = new System.Drawing.Point(274, 3);

When the form is resized, the bottom panel that contains the button resized with it. The button then moves along the X-axis by the width difference between the child panel and the base panel. For example, the bottom panel in the Base Form above is 199 pixels wide. The bottom panel in one of my child forms was 352 pixels wide. So when I saved the child form and opened it later, the button started out at (274, 3) and then shifted right by 352 – 199 = 153 pixels and rendered itself at (427, 3). Roland Weigelt wrote a very nice and detailed post on this almost 6 years ago. The “DockPadding” property he mentions has since become “Padding”, but the advice otherwise seems to still hold. He suggests the following solution:

The secret is the right combination of docking and dock padding.

That’s it right there. I went back to the base form and adjusted the following:

  • Set bottom panel’s Padding to Left = 0, Top = 5, Bottom = 5, Right = 4;
  • Set the button’s Dock to “Right”;
  • Rebuild my solution.

Here’s the result:

Child Form (Fixed)