Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TPanel does not AutoSize when containing a TPanel

I have a panel inside another:

enter image description here

The inner panel is aligned alTop:

enter image description here

And the outer panel is set to AutoSize=true:

enter image description here

And everything sizes. If i changes the height of the inner panel at design time, the outer panel auto sizes to accommodate it:

enter image description here

And now runtime

Now i need to change the height of the inner panel at runtime:

procedure TForm2.Button1Click(Sender: TObject);
begin
    pnlInner.Height := pnlInner.Height + 50;
    lblPointer.Top := pnlOuter.Top + pnlInner.Height;
end;

Except when i change the height of the inner panel at runtime, the autosize panel does not autosize:

enter image description here

This of course worked in Delphi 5, 7, and probably XE2 - XE5.

What's the fix?

The workaround is, of course, to bypass Alignment/Autosize and do everything during various OnResize events. But that's distinctly not RAD. I'm sure it's a small bug in the VCL somewhere. And since we already have about two-dozen XE6 VCL bugs that we've patched, it would be better to fix it so nobody else has to think about it.

Bonus Chatter

I love the line:

and, could you please attach sample project?

It's almost as if nobody bothered to even try to reproduce it.

like image 276
Ian Boyd Avatar asked Apr 01 '15 15:04

Ian Boyd


2 Answers

The issue is a regression in TWinControl.AlignControls:

procedure TWinControl.AlignControls(AControl: TControl; var Rect: TRect);
begin
   //...snip

   // Apply any constraints
   if Showing and ((sfWidth in FScalingFlags) or (sfHeight in FScalingFlags)) then
      DoAdjustSize;

   //...snip
end;

The bug here is that it will not call DoAdjustSize unless either sfWidth or sfHeight scaling flags are present.

The fix is to not try to outsmart yourself, and DoAdjustSize regardless:

procedure TWinControl.AlignControls(AControl: TControl; var Rect: TRect);
begin
   //...snip

   // Apply any constraints
   //QC125995: Don't look to scaling flags to decide if we should adjust size
   if Showing {and ((sfWidth in FScalingFlags) or (sfHeight in FScalingFlags))} then
      DoAdjustSize;

   //...snip
end;

With this fix found, we're halfway to solving the similar issue except with a TOleControl (e.g. TWebBrowser) rather than a TPanel.

Note: Any code released into public domain. No attribution required.

like image 111
Ian Boyd Avatar answered Nov 15 '22 04:11

Ian Boyd


This is reported in Embarcaderos Quality Central:

  • QC125995: [Regression in XE6 Update1] TPanel.AutoSize is not working
  • QC129330: AutoSize property is not always applied

I can reproduce this with XE6, but not with XE7.

like image 31
Tom Brunberg Avatar answered Nov 15 '22 02:11

Tom Brunberg