layoutresizeheightfiremonkeytpanel

Resize a TLayout according to the number of labels in Firemonkey


here is my sample code in 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 is a dynamic array no always with the same number of elements, so I resize a TPanel (Panel1) with the contents of TLayout (Layout1) according with number of labels;

Panel1.Height := Layout1.ChildrenRect.Height

This works fine when the number of labels grows in Layout1, but when the number of labels is less, Layout1.ChildrenRect.Height has no effect and not shrinks it, height of the Layout1 always keeps the higher value.

Is there any solution or any other alternative to how to do it?, thanks Regards.


Solution

  • I hope that this code will help in that. I apologize for more editing, this is last, but I was trying again and the code was not entirely correct.

    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;