包含 TPanel 时,TPanel 不会自动调整大小

TPanel does not AutoSize when containing a TPanel

我在另一个里面有一个面板:

内面板对齐alTop:

并且外面板设置为AutoSize=true:

所有尺寸。如果我在设计时更改了内面板的 高度,外面板 auto sizes 以适应它:

现在运行时

现在我需要 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;

除非我在运行时更改内部面板的高度,autosize面板不会autosize:

这当然适用于 Delphi 5、7 和 probably XE2 - XE5

修复了什么?

当然,解决方法是绕过 Alignment/Autosize 并在各种 OnResize[= 期间执行所有操作67=] 事件。但这显然不是 RAD。我确定这是 VCL 某处的一个小错误。由于我们已经修补了大约两个 XE6 VCL 错误,最好修复它,这样其他人就不必考虑它了。

奖金聊天

我喜欢这句话:

and, could you please attach sample project?

几乎没有人愿意尝试复制它。

这是在 Embarcaderos Quality Central 中报告的:

  • QC125995:[XE6 Update1 中的回归] TPanel.AutoSize 不工作
  • QC129330:AutoSize 属性 并不总是适用

我可以用 XE6 重现这个,但不能用 XE7。

问题是 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;

这里的错误是它不会调用 DoAdjustSize 除非存在 sfWidthsfHeight 缩放标志。

解决方法是不要试图战胜自己,DoAdjustSize无论如何:

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;

找到此修复后,我们已经完成了解决 the similar issue except with a TOleControl (e.g. TWebBrowser) rather than a TPanel.

的一半任务

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