我试图以下列方式使用TFlowPanel组件:
Form1
组件FlowPanel1: TFlowPanel
上。 Form1.Width = 400
,FlowPanel1.Align = alTop
,FlowPanel1.AutoSize = True
,FlowPanel1.AutoWrap = True
。 FlowPanel1
5个SpeedButtons上,并将Width
设置为64. Form1.Width = 200
)。出于某种原因,当用户调整表单大小时,速度按钮不会自动排成两行。虽然,AutoSize = False
,AutoWrap = True
时,它们会排成两行
这种行为的原因是什么以及如何解决?
编辑:我发现了“快速而肮脏”的解决方案。以下代码是TFlowPanel.OnResize
事件的事件处理程序:
procedure TForm1.FlowPanel1Resize(Sender: TObject);
begin
with FlowPanel1 do
begin
AutoSize := False;
Realign; // line up controls
AutoSize := True; // adjust TFlowPanel.Height
end;
end;
但是,我仍然想知道是否有一种解决问题的标准方法。
答案 0 :(得分:4)
我无法在代码中找到此类行为的确切原因,但基本上您已经挑战了两个要调整的大小调整属性AutoSize
和Align
。我认为问题在于,当您调整表单大小时,将AutoSize
配置为True并将Align
设置为alTop
的控件将首先尝试自动调整控件,然后对齐顶部它的父母。我可以肯定地说,这两个属性至少不应该与它们的逻辑含义相结合。
我建议您的解决方法是默认关闭自动调整大小,并在OnResize
事件中将其临时打开并重新关闭以自动调整高度。所以在代码中它会简单地改为:
procedure TForm1.FlowPanel1Resize(Sender: TObject);
begin
// there's no Realign here, since the AlignControls request is called
// at control resize, so here you have children already aligned, what
// you then need is to request the control to autosize the height and
// turn off the autosizing to the default, disabled state
FlowPanel1.AutoSize := True;
FlowPanel1.AutoSize := False;
end;
答案 1 :(得分:4)
tl,博士:这是
TFlowPanel
中的错误。
通常情况下,默认情况下AutoSize
和Align
属性非常合适,因为这已经在TControl
级别处理了,所以我想知道为什么会发生这种情况。我注意到AlignControls
中的覆盖TFlowPanel
方法,并考虑绕过它进行测试:
type
TWinControlAccess = class(TWinControl);
TAlignControls = procedure(Instance: TObject; AControl: TControl;
var Rect: TRect);
TFlowPanel = class(Vcl.ExtCtrls.TFlowPanel)
protected
procedure AlignControls(AControl: TControl; var Rect: TRect); override;
end;
TForm1 = class(TForm)
...
procedure TFlowPanel.AlignControls(AControl: TControl; var Rect: TRect);
begin
// Skip TCustomFlowPanel.AlignControls
TAlignControls(@TWinControlAccess.AlignControls)(Self, AControl, Rect);
end;
procedure TForm1.FlowPanel1Resize(Sender: TObject);
begin
// Do my own aligning of the last button
if FlowPanel1.ClientWidth < Button5.BoundsRect.Right then
begin
Button5.Left := 1;
Button5.Top := Button1.Height + 1;
end
else if FlowPanel1.ClientWidth > Button4.BoundsRect.Right + Button5.Width then
begin
Button5.Left := Button4.BoundsRect.Right;
Button5.Top := 1;
end;
end;
现在,这可以按预期工作。那么TFlowPanel
实施AlignControls
会出现什么问题?看起来像下面的代码片段是:
if AutoSize then
Rect := TRect.Create(
Rect.Left,
Rect.Top,
Rect.Left + (ExplicitWidth - (Width - (Rect.Right - Rect.Left))),
Rect.Top + (ExplicitHeight - (Height - (Rect.Bottom - Rect.Top))));
当此部分被注释掉时,行为与预期一样Align
设置。现在,我想将其提交给QC,但也许我忽略了它的一些方面。请编辑或评论何时(以及为什么)确实需要此代码。