0

i've a TExpander component and i add some TTexts to it at runtime , the issue i'm facing is : how can this Expander's height be set based on the Number of the TTexts , something like AutoSize ?

the code i'm using :

procedure TForm1.Button5Click(Sender: TObject);
var
  _DailyEvent:TDailyEvents;
  Eventstext:TText;
  _Y:Integer;
begin
    _Y:=10;
    For _DailyEvent in DailyEventsList do
    begin
             Eventstext:=TText.Create(Self);
             Eventstext.Position.Y := _Y;
             Eventstext.Align:=TAlignLayout.Top;
             Eventstext.Height:=25;
             Eventstext.TagString:=_DailyEvent.EventID;
             Eventstext.Text:=_DailyEvent.EventName;
             Eventstext.Parent:=Expander1;
             inc(_Y, 15);
    end;
    Expander1.Height:=?   

end;

here's what i get

Image demonstrating problem

thank you .

Michael
  • 1,089
  • 1
  • 11
  • 28
randydom
  • 395
  • 2
  • 20

1 Answers1

1

Actually, when you set Eventstext.Parent to expander1, this object added to protected field FContent. So, if you want calculate real size as sum of all inner controls, you must get this field.

You can "override" TExpander class like this:

type
  // declare new TExpander class before form declaration
  // thanks to this declaration we have access to protected fields
  TExpander = class(FMX.StdCtrls.TExpander)
  protected
    procedure DoExpandedChanged; override;
  public
    function GetRealRect: TRectF;
  end;

  TForm2 = class(TForm)
    expndr1: TExpander; // this is our new class, not "standart" TExpander
    btnAdd10: TButton;
    btnDelLast: TButton;
    procedure btnAdd10Click(Sender: TObject);
    procedure btnDelLastClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.fmx}

procedure TForm2.btnAdd10Click(Sender: TObject);
var
  Eventstext: TText;
  i: integer;
  _Y: integer;
begin
  _Y := 10;
  For i := 1 to 10 do
  begin
    Eventstext := TText.Create(Self);
    Eventstext.Position.Y := _Y;
    Eventstext.Align := TAlignLayout.Top;
    Eventstext.Height := 25;
    Eventstext.Text := i.ToString;
    Eventstext.Parent := expndr1;
    inc(_Y, 25);
  end;
  // of course, this is not real Autosize,
  // you can override AddObject in TExpander and change size in it,
  // but you can`t get access to RemoveObject in FContent...
  // thus, "AutoSize" will be limited only to adding items.
  // I think the current way is much better than override AddObject...
  expndr1.SetBoundsRect(expndr1.GetRealRect); 
  // or expndr1.height:=expndr1.GetRealRect.Height;
end;

procedure TForm2.btnDelLastClick(Sender: TObject);
begin
  if expndr1.FContent.ChildrenCount <> 0 then
  begin
    expndr1.FContent.Children[expndr1.FContent.ChildrenCount - 1].Release;
    expndr1.SetBoundsRect(expndr1.GetRealRect);
  end;
end;

{ TExpander }

procedure TExpander.DoExpandedChanged;
begin
  inherited;
  SetBoundsRect(GetRealRect);
end;

function TExpander.GetRealRect: TRectF;
var
  i: integer;
  LControl: TControl;
begin
  // above FContent are Button, Text and Checkbox
  Result.TopLeft := AbsoluteRect.TopLeft;
  Result.BottomRight := FContent.AbsoluteRect.TopLeft;

  if FIsExpanded then
    for i := 0 to FContent.ChildrenCount - 1 do
      if FContent.Children[i] is TControl then
      begin
        LControl := TControl(FContent.Children[i]);
        if LControl.Visible then
          UnionRectF(Result, Result, LControl.ChildrenRect);
      end;
  if Result.Width = 0 then // if there are no controls in FContent.
    Result.Width := Width;
end;
kami
  • 1,438
  • 1
  • 16
  • 23