实际上,当您设置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;