VB.NET: I controlli ancorati ereditati non mantengono la posizione corretta

Quando si costruisce una form ereditata da un’altra che conteneva dei controlli con l’impostazione Anchor non mantengono la posizione corretta se si modifica la dimensione della form ereditata in particolare se i controlli hanno l’Anchor impostato su Bottom.

Il problema è in effetti noti e descritto nella KB 316560 FIX: Anchored Control on Inherited Form Changes Location When You Recompile:

“After you run or recompile a project, anchored controls may be restored to their original position on the base form.
When you create a new Windows Form by inheriting from a base form that has private anchored controls, you may encounter unexpected run-time and design-time behavior. When you first resize the inherited form in the designer, the controls move correctly with the form; however, at run time or when you recompile, the controls are restored to their original position on the base form.”

Sempre nella KB 316560 vengono dati due suggerimenti su come risolvere il problema:

You can work around this problem by using one of the following methods:

  • Wait until after you run InitializeComponent to resize the form. Do not resize the form in the designer.
  • In the base form, change the access modifier of anchored controls (for example, button1) to be Protected in the base class, as follows:
    – In Microsoft Visual C#, change Private to Protected:

    Protected System.Windows.Forms.Button button1;
    – In Microsoft Visual Basic .NET, change Friend to Protected:
    Protected WithEvents Button1 As System.Windows.Forms.Button

Sebbene la KB 316560 riporti che il problema è stato corretto nel Microsoft .NET Framework SDK 1.1 io l’ho rilevato su un progetto VB.NET in Visual Studio 2013 impostato per utilizzare .NET 4.5.

Per risolverlo ho modificato l’access modifier dei controlli da Friend a Protected, va precisato che se nelle form ereditate è stata modificata la dimensione prima di intervenire sull’access modifier dei controlli occorre eliminare manualmente dal file designer.vb della form ererditata le righe di codice relative al size della form:

Me.AutoScaleDimensions = New System.Drawing.SizeF(…, …)

Me.ClientSize = New System.Drawing.Size(…, …)

Quindi reimpostare la dimensione desiderata dal designer.