根据 Firemonkey 中的标签数量调整 TLayout 的大小
Resize a TLayout according to the number of labels in Firemonkey
这是我在 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 是一个动态数组,并不总是具有相同数量的元素,因此我根据标签数量调整了 TPanel (Panel1) 的大小,其中包含 TLayout (Layout1) 的内容;
Panel1.Height := Layout1.ChildrenRect.Height
当Layout1的label数量增加时,这个可以正常工作,但是当label数量较少时,Layout1.ChildrenRect.Height
没有效果,不会收缩,Layout1的高度总是保持较高的值。
是否有任何解决方案或其他替代方法?谢谢
问候。
我刚刚提交了以下错误报告。与此同时,我建议您自己计算边界,甚至可以从以下代码开始:
FMX TControl.ChildrenRect 的文档指出:
"指定当前控件的子控件所占据的矩形区域。
ChildrenRect 是通过对控件的子控件所占据的矩形进行并集运算得到的矩形。" - http://docwiki.embarcadero.com/Libraries/XE7/en/FMX.Controls.TControl.ChildrenRect
但是,代码实际上在计算中包含了它自己的边界:
function TControl.GetChildrenRect: TRectF;
var
I: Integer;
Control: TControl;
begin
Result := AbsoluteRect; <---*****This line
{ children }
if not (ClipChildren or SmallSizeControl) and (FControls <> nil) then
for I := GetFirstVisibleObjectIndex to GetLastVisibleObjectIndex - 1 do
begin
Control := FControls[I];
if Control.Visible then
Result := UnionRect(Result, Control.GetChildrenRect);
end
end;
如果这是预期的行为,那么文档需要更新,否则就是实现中的错误。
我希望这段代码对此有所帮助。
对于更多的编辑,我深表歉意,这是最后一次,但我再次尝试,代码并不完全正确。
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;
这是我在 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 是一个动态数组,并不总是具有相同数量的元素,因此我根据标签数量调整了 TPanel (Panel1) 的大小,其中包含 TLayout (Layout1) 的内容;
Panel1.Height := Layout1.ChildrenRect.Height
当Layout1的label数量增加时,这个可以正常工作,但是当label数量较少时,Layout1.ChildrenRect.Height
没有效果,不会收缩,Layout1的高度总是保持较高的值。
是否有任何解决方案或其他替代方法?谢谢 问候。
我刚刚提交了以下错误报告。与此同时,我建议您自己计算边界,甚至可以从以下代码开始:
FMX TControl.ChildrenRect 的文档指出:
"指定当前控件的子控件所占据的矩形区域。 ChildrenRect 是通过对控件的子控件所占据的矩形进行并集运算得到的矩形。" - http://docwiki.embarcadero.com/Libraries/XE7/en/FMX.Controls.TControl.ChildrenRect
但是,代码实际上在计算中包含了它自己的边界:
function TControl.GetChildrenRect: TRectF;
var
I: Integer;
Control: TControl;
begin
Result := AbsoluteRect; <---*****This line
{ children }
if not (ClipChildren or SmallSizeControl) and (FControls <> nil) then
for I := GetFirstVisibleObjectIndex to GetLastVisibleObjectIndex - 1 do
begin
Control := FControls[I];
if Control.Visible then
Result := UnionRect(Result, Control.GetChildrenRect);
end
end;
如果这是预期的行为,那么文档需要更新,否则就是实现中的错误。
我希望这段代码对此有所帮助。 对于更多的编辑,我深表歉意,这是最后一次,但我再次尝试,代码并不完全正确。
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;