TFlowPanel中的AutoSize和AutoWrap冲突

时间:2012-09-12 04:11:14

标签: delphi delphi-xe2 vcl autosize

我试图以下列方式使用TFlowPanel组件:

  1. 放置在主要表单Form1组件FlowPanel1: TFlowPanel上。
  2. 设置Form1.Width = 400FlowPanel1.Align = alTopFlowPanel1.AutoSize = TrueFlowPanel1.AutoWrap = True
  3. 放置在FlowPanel1 5个SpeedButtons上,并将Width设置为64.
  4. 编译并运行。
  5. 缩小表单的宽度(约为Form1.Width = 200)。
  6. 出于某种原因,当用户调整表单大小时,速度按钮不会自动排成两行。虽然,AutoSize = FalseAutoWrap = 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;
    

    但是,我仍然想知道是否有一种解决问题的标准方法。

2 个答案:

答案 0 :(得分:4)

我无法在代码中找到此类行为的确切原因,但基本上您已经挑战了两个要调整的大小调整属性AutoSizeAlign。我认为问题在于,当您调整表单大小时,将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中的错误。

通常情况下,默认情况下AutoSizeAlign属性非常合适,因为这已经在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,但也许我忽略了它的一些方面。请编辑或评论何时(以及为什么)确实需要此代码。