我在TFlowLayout
内有一个TVertScrollbox
的表单。
我在运行时用TFlowLayout
填充了一些帧,这些帧可以有不同的高度。
我想将VertScrollBox.ContentBounds
设置为能够从添加的第一帧滚动到最后一帧。
似乎我必须使用CalcContentBounds
的{{1}}。我怎么能这样做?
TVertScrollBox
Unit1.pas
procedure TForm1.Button2Click(Sender: TObject);
var
fr:TfrFrameItem;
i:integer;
begin
FlowLayout1.BeginUpdate;
for i:=FlowLayout1.ControlsCount-1 downto 0 do begin
FlowLayout1.Controls[i].Free;
end;
for i:=0 to 100 do begin
fr:=TfrFrameItem.Create(FlowLayout1);
fr.Name:='fr'+FlowLayout1.ControlsCount.ToString();
fr.Parent:=FlowLayout1;
fr.Visible:=True;
end;
FlowLayout1.EndUpdate;
VertScrollBox1.RealignContent;
end;
procedure TForm1.VertScrollBox1CalcContentBounds(Sender: TObject;
var ContentBounds: TRectF);
begin
ContentBounds.Bottom:=?????
end;
Unit1.fmx
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
FMX.Controls.Presentation, FMX.StdCtrls,Math, FMX.Objects, FMX.Edit,
FMX.ListBox, FMX.ScrollBox, FMX.Memo, FMX.TabControl, FMX.MultiView;
type
TForm1 = class(TForm)
VertScrollBox1: TVertScrollBox;
FlowLayout1: TFlowLayout;
Panel1: TPanel;
ToolBar1: TToolBar;
Button2: TButton;
procedure Button2Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses uFrameitem;
{$R *.fmx}
procedure TForm1.Button2Click(Sender: TObject);
var
lFrame:TfrFrameItem;
i:integer;
lHeight:single;
begin
FlowLayout1.BeginUpdate;
try
for i := FlowLayout1.ControlsCount - 1 downto 0 do
FlowLayout1.Controls[i].Free;
lHeight := 0;
for i := 0 to 100 do
begin
lFrame := TfrFrameItem.Create(FlowLayout1);
lFrame.Name := 'fr' + FlowLayout1.ControlsCount.ToString;
lFrame.Parent := FlowLayout1;
lFrame.Visible := True;
lHeight := Max(lHeight, lFrame.Position.Y + lFrame.Height);
end;
FlowLayout1.Height := lHeight;
finally
FlowLayout1.EndUpdate;
end;
VertScrollBox1.RealignContent;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var i:integer;
begin
for i:=FlowLayout1.ControlsCount-1 downto 0 do begin
FlowLayout1.Controls[i].Free;
end;
end;
end.
uFrameItem.pas
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 647
ClientWidth = 1057
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnDestroy = FormDestroy
DesignerMasterStyle = 0
object VertScrollBox1: TVertScrollBox
Align = Client
Size.Width = 1057.000000000000000000
Size.Height = 568.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
Viewport.Width = 1057.000000000000000000
Viewport.Height = 568.000000000000000000
object FlowLayout1: TFlowLayout
Align = Top
Size.Width = 1057.000000000000000000
Size.Height = 177.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
Justify = Left
JustifyLastLine = Left
FlowDirection = LeftToRight
end
end
object Panel1: TPanel
Align = Bottom
Position.Y = 608.000000000000000000
Size.Width = 1057.000000000000000000
Size.Height = 39.000000000000000000
Size.PlatformDefault = False
TabOrder = 2
end
object ToolBar1: TToolBar
Size.Width = 1057.000000000000000000
Size.Height = 40.000000000000000000
Size.PlatformDefault = False
TabOrder = 3
object Button2: TButton
Align = Right
Position.X = 977.000000000000000000
Size.Width = 80.000000000000000000
Size.Height = 40.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
Text = 'Preencher'
OnClick = Button2Click
end
end
end
uFrameItem.fmx
unit uFrameItem;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
FMX.Controls.Presentation, FMX.Objects, FMX.Layouts;
type
TfrFrameItem = class(TFrame)
Layout1: TLayout;
Rectangle1: TRectangle;
Label1: TLabel;
Label2: TLabel;
Label4: TLabel;
Layout2: TLayout;
Label3: TLabel;
Label6: TLabel;
Layout3: TLayout;
Label7: TLabel;
Label8: TLabel;
Button1: TButton;
Rectangle2: TRectangle;
Label5: TLabel;
procedure Layout2Resize(Sender: TObject);
procedure Label2Resize(Sender: TObject);
private
{ Private declarations }
function ListChildren(Obj : TFMXObject; Level : Integer):double;
public
{ Public declarations }
end;
implementation
{$R *.fmx}
function TfrFrameItem.ListChildren(Obj : TFMXObject; Level : Integer):double;
var i: Integer;
begin
for i := 0 to Obj.ChildrenCount-1 do begin
if Obj.Children[i].Tag=1 then begin
if (Obj.Children[i] is TLayout) then
result:=result+TLayout(Obj.Children[i]).Height;
if (Obj.Children[i] is TLabel) then
result:=result+TLabel(Obj.Children[i]).Height;
if (Obj.Children[i] is TImageControl) then
result:=result+TImageControl(Obj.Children[i]).Height;
if (Obj.Children[i] is TButton) then
result:=result+TButton(Obj.Children[i]).Height;
end;
result:=result+ListChildren(Obj.Children[i],Level+1);
end;
end;
procedure TfrFrameItem.Label2Resize(Sender: TObject);
const
ExtraHeigthOfLayout = 10;
var
Lbl: TLabel;
Layout: TLayout;
begin
Layout2Resize(Sender);
end;
procedure TfrFrameItem.Layout2Resize(Sender: TObject);
const
ExtraHeigthOfLayout = 10;
var
Lay: Tlayout;
Layout: TLayout;
i:integer;
hh:double;
begin
hh:=ListChildren(Layout1,0);
Layout1.Height:=hh+60;
end;
end.
答案 0 :(得分:0)
您根本不需要更改TVertScrollBox
。它会自动调整其内容。您只需要更改TFlowLayout
的大小。在这种情况下,只要表单的大小发生变化,就必须重新计算大小。
因此,您必须将VertScrollBox1.RealignContent
替换为Self.Resize
,然后指定表单OnResize
事件。
procedure TForm1.FormResize(Sender: TObject);
begin
if FlowLayout1.ControlsCount > 0 then
FlowLayout1.Height := FlowLayout1.Controls.Last.BoundsRect.Bottom
else
FlowLayout1.Height := VertScrollBox1.Height;
end;