0

这是我在 Firemonkey 中的示例代码;

var
   f: integer; 
   Label1: TLabel;
   MyStringArray: TArray<String>;
   Panel1: TPanel;
   Layout1: TLayout;
begin
   Layout1.Align := TAlignLayout.Client;
   MyStringArray := ['aa','bb','cc','dd','ee','ff'];
   f:= 10;
   Layout1.BeginUpdate;
   for i := 0 to length(MyStringArray) - 1 do
   begin
        Label1 := TLabel.Create(Self);
        Label1.Name := 'Label' + i.ToString;
        Label1.Text := 'Label_' + MyStringArray[i];
        Label1.Position.Y := f;
        Label1.Align := TAlignLayout.Top;
        Label1.Parent := Layout1;
        inc(f, 15);
   end;
   Layout1.EndUpdate;
end; 

MyStringArray 是一个动态数组,不总是具有相同数量的元素,因此我根据标签数量调整了 TLayout (Layout1) 内容的 TPanel (Panel1) 的大小;

Panel1.Height := Layout1.ChildrenRect.Height

当 Layout1 中的标签数量增加时,这可以正常工作,但是当标签数量较少时,Layout1.ChildrenRect.Height没有效果并且不缩小它,Layout1 的高度始终保持较高的值。

是否有任何解决方案或任何其他替代方法?,谢谢问候。

4

2 回答 2

1

我希望这段代码对此有所帮助。我为更多的编辑道歉,这是最后一次,但我又试了一次,代码并不完全正确。

type
  TControlHelper = class helper for TControl
  public
    function ChildrenWidth: Single; 
    function ChildrenHeight: Single; 
  end;

function TControlHelper.ChildrenWidth: Single;
var
  VIndex: Integer;
  VControl: TControl;
  VRect: TRectF;
begin
  VRect := TRectF.Empty;
  if not ( ClipChildren or SmallSizeControl ) and ( Controls <> nil ) then
  begin
    for VIndex := GetFirstVisibleObjectIndex to GetLastVisibleObjectIndex - 1 do
    begin
      VControl := Controls[ VIndex ];
      if VControl.Visible then
        VRect := UnionRect( VRect, VControl.Margins.MarginRect( TRectF.Create( VControl.Position.Point, VControl.Width, VControl.Height ) ) );
    end;
    Result := VRect.Width + Padding.Right;
  end;
end;

function TControlHelper.ChildrenHeight: Single;
var
  VIndex: Integer;
  VControl: TControl;
  VRect: TRectF;
begin
  VRect := TRectF.Empty;
  if not ( ClipChildren or SmallSizeControl ) and ( Controls <> nil ) then
  begin
    for VIndex := GetFirstVisibleObjectIndex to GetLastVisibleObjectIndex - 1 do
    begin
      VControl := Controls[ VIndex ];
      if VControl.Visible then
        VRect := UnionRect( VRect, VControl.Margins.MarginRect( TRectF.Create( VControl.Position.Point, VControl.Width, VControl.Height ) ) );
    end;
    Result := VRect.Height + Padding.Bottom;
  end;
end;
于 2015-03-26T23:57:40.670 回答
1

我刚刚提交了以下内容作为错误报告。同时,我建议您自己计算界限,甚至可以从以下代码开始:

FMX TControl.ChildrenRect 的文档指出:

“指定当前控件的子控件占用的矩形区域。ChildrenRect是控件子控件占用的矩形之间进行并集运算得到的矩形。” - http://docwiki.embarcadero.com/Libraries/XE7/en/FMX.Controls.TControl.ChildrenRect

但是,代码实际上在计算中包含了它自己的界限:

function TControl.GetChildrenRect: TRectF;
var
  I: Integer;
  Control: TControl;
begin
  Result := AbsoluteRect;  <---*****This line
  { children }
  if not (ClipChildren or SmallSizeControl) and (FControls <> nil) then
    for I := GetFirstVisibleObjectIndex to GetLastVisibleObjectIndex - 1 do
    begin
      Control := FControls[I];
      if Control.Visible then
        Result := UnionRect(Result, Control.GetChildrenRect);
    end
end;

如果这是预期的行为,那么文档需要更新,否则它是实现中的错误。

于 2015-02-16T16:42:20.630 回答