Delphi устанавливает высоту TExpander

У меня есть компонент TExpander, и я добавляю некоторые TTexts к нему во время выполнения, проблема, с которой я сталкиваюсь: как можно настроить высоту этого Expander на основе количества TTexts, что-то вроде AutoSize?

код, который я использую:

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;

вот что я получаю

Изображение, демонстрирующее проблему

благодарю вас.

1 ответ

Решение

На самом деле, когда вы установите Eventstext.Parent в expander1, этот объект добавлен в защищенное поле FContent, Итак, если вы хотите рассчитать реальный размер как сумму всех внутренних элементов управления, вы должны получить это поле.

Вы можете "переопределить" TExpander класс как это:

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;
Другие вопросы по тегам