Search code examples
delphifiremonkey

Adding Components at runtime to GridPanelLayout


I am trying to add a group of components at runtime to a GridpanelLayout. In this case 4 sets, each set is a Tlable Tbutton Tedit Tbutton . Each Component should be in 1 row and each in its own column.

When I run the code below, it will add 2 sets of components and the Tbutton , TEdit , and TButton of the first set does not align with column when resizeing , but all other components do. Below is my code. Also Note I have a TLayout and the TGridPanelLayout is inside the TLayout aligned to client.

procedure TForm5.Button1Click(Sender: TObject);
var
I,K : integer;
Namelabel : TLabel;
MinusButton, PlusButton : TButton;
EditCount : TEdit;
begin
  I:= 0;
  K:= 0;


 for I := 0 to 2 do
  Begin
  namelabel := Tlabel.Create(self);
  MinusButton := TButton.Create(self);
  EditCount := TEdit.Create(self);
  PlusButton := TButton.Create(self);

  Namelabel.name := 'LabelField_'+i.ToString;
  MinusButton.Name := 'MinusField_'+i.ToString;
  PlusButton.Name := 'PlusField_'+I.ToString;
  EditCount.Name := 'EditField_'+i.ToString;

  MinusButton.Text := '-';
  PlusButton.Text := '+';

  MinusButton.Width := 20;
  PlusButton.Width := 20;

  namelabel.Parent := GridPanelLayout1;
  MinusButton.Parent := GridPanelLayout1;
  EditCount.Parent := GridPanelLayout1;
  PlusButton.Parent := GridPanelLayout1;


  GridPanelLayout1.BeginUpdate;
  GridPanelLayout1.RowCollection.BeginUpdate;
    if i <> 0 then
      begin
        GridpanelLayout1.RowCollection.Add;
        GridPanelLayout1.RowCollection[i].SizeStyle := TGridpanelLayout.TSizeStyle.Auto;
      end;
  GridPanelLayout1.RowCollection.EndUpdate;
    With GridpanelLayout1 do
      begin
      ControlCollection.BeginUpdate;
        ControlCollection.Add;
        controlcollection[i+k].Column := 0;
        ControlCollection[i+k].Row := i;
        controlcollection[i+k].ColumnSpan := 1;
        ControlCollection[i+k].RowSpan := 1;
        ControlCollection[i+k].Control := (namelabel);
        K:= K+1;

        ControlCollection.Add;
        controlcollection[i+k].Column := 1;
        ControlCollection[i+k].Row := i;
        controlcollection[i+k].ColumnSpan := 1;
        ControlCollection[i+k].RowSpan := 1;
        ControlCollection[i+k].Control := (MinusButton);
        K:= K+1;

        ControlCollection.Add;
        controlcollection[i+k].Column := 2;
        ControlCollection[i+k].Row := i;
        controlcollection[i+k].ColumnSpan := 1;
        ControlCollection[i+k].RowSpan := 1;
        ControlCollection[i+k].Control := (EditCount);
        K:= K+1;

        ControlCollection.Add;
        controlcollection[i+k].Column := 3;
        ControlCollection[i+k].Row := i;
        controlcollection[i+k].ColumnSpan := 1;
        ControlCollection[i+k].RowSpan := 1;
        ControlCollection[i+k].Control := (PlusButton);
        K:= K+1;
      controlCollection.EndUpdate;
      showmessage(inttostr(RowCollection.Count))
      end;

  GridPanelLayout1.EndUpdate;
  End;

end;

UPDATE***** Addeing image of before and after. Before - Everything is align. Before

After resizeing form After

FMX File
object Form5: TForm5
  Left = 0
  Top = 0
  Caption = 'Form5'
  ClientHeight = 480
  ClientWidth = 640
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  DesignerMasterStyle = 0
  object Layout1: TLayout
    Align = Client
    Size.Width = 640.000000000000000000
    Size.Height = 430.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 0
    object GridPanelLayout1: TGridPanelLayout
      Align = Client
      Size.Width = 640.000000000000000000
      Size.Height = 430.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 0
      ColumnCollection = <
        item
          Value = 25.366992464791410000
        end
        item
          Value = 24.910521746363720000
        end
        item
          Value = 24.580453329747010000
        end
        item
          Value = 25.142032459097870000
        end>
      ControlCollection = <>
      RowCollection = <
        item
          SizeStyle = Auto
          Value = 100.000000000000000000
        end
        item
          SizeStyle = Auto
          Value = 100.000000000000000000
        end>
    end
  end
  object Layout2: TLayout
    Align = Bottom
    Position.Y = 430.000000000000000000
    Size.Width = 640.000000000000000000
    Size.Height = 50.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 1
    object Button1: TButton
      Position.X = 440.000000000000000000
      Position.Y = 16.000000000000000000
      TabOrder = 0
      Text = 'Button1'
      OnClick = Button1Click
    end
    object Label1: TLabel
      Position.X = 32.000000000000000000
      Position.Y = 16.000000000000000000
      Text = 'Label1'
      TabOrder = 1
    end
    object Edit1: TEdit
      Touch.InteractiveGestures = [LongTap, DoubleTap]
      TabOrder = 2
      Position.X = 224.000000000000000000
      Position.Y = 16.000000000000000000
    end
  end
end

Solution

  • The controls that you create at the beginning of the loop are added to the GridPanelLayout1 when you assign the parent of those controls:

    Namelabel.Parent := GridPanelLayout1;
    MinusButton.Parent := GridPanelLayout1;
    EditCount.Parent := GridPanelLayout1;
    PlusButton.Parent := GridPanelLayout1;
    

    Your code that adds the controls to the ControlCollection messes up the internal book keeping.

    So, after the code:

    GridPanelLayout1.BeginUpdate;
    
      GridPanelLayout1.RowCollection.BeginUpdate;
    
        GridPanelLayout1.RowCollection.Add;
        GridPanelLayout1.RowCollection[I].SizeStyle :=
          TGridPanelLayout.TSizeStyle.Auto;
    

    remove the code ...

        With GridPanelLayout1 do
        begin
          ControlCollection.BeginUpdate;
    ...
        end;
    

    until

        GridPanelLayout1.RowCollection.EndUpdate;
    
    GridPanelLayout1.EndUpdate;
    

    ... and the controls are correctly parented and inserted in the rows/columns as you wanted them.

    I noticed one more issue, and that is the size reduction when you contract the grid panel. The controls do not return to original width when you widen the grid again. As that is another issue, I have to, for now, leave it to you to consider what you want to do.


    Update regarding the problem when resizing (contracting) the form width. Delphi 11 FMX TForm now has a Constraints property as the VCL Tform has had "forever" (or as long as I remember). Still only a band-aid IMO.