【问题标题】:How to set TvertScollBox to scroll items in Delphi FireMonkey如何设置 TvertScollBox 在 Delphi FireMonkey 中滚动项目
【发布时间】:2018-03-25 23:15:17
【问题描述】:

我有一个在TVertScrollbox 内带有TFlowLayout 的表单。

我在运行时用一些帧填充TFlowLayout,它们的高度可以变化。

我想将VertScrollBox.ContentBounds 设置为能够从添加的第一帧滚动到最后一帧。

看来我必须使用TVertScrollBox 中的CalcContentBounds。我该怎么办?

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.pas

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.

Unit1.fmx

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.pas

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.

uFrameItem.fmx

object frFrameItem: TfrFrameItem
  Size.Width = 210.000000000000000000
  Size.Height = 391.000000000000000000
  Size.PlatformDefault = False
  object Layout1: TLayout
    StyleName = 'mystyle'
    Position.X = 5.000000000000000000
    Position.Y = 5.000000000000000000
    Size.Width = 201.000000000000000000
    Size.Height = 381.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 2
    object Rectangle1: TRectangle
      Align = Client
      Fill.Color = claLimegreen
      Padding.Left = 5.000000000000000000
      Padding.Right = 5.000000000000000000
      Size.Width = 201.000000000000000000
      Size.Height = 381.000000000000000000
      Size.PlatformDefault = False
      object Label1: TLabel
        Tag = 1
        Align = Top
        StyledSettings = [Family, FontColor]
        Padding.Top = 10.000000000000000000
        Padding.Bottom = 10.000000000000000000
        Margins.Top = 10.000000000000000000
        Margins.Bottom = 10.000000000000000000
        Position.X = 5.000000000000000000
        Position.Y = 10.000000000000000000
        Size.Width = 191.000000000000000000
        Size.Height = 17.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Size = 18.000000000000000000
        TextSettings.Font.Style = [fsBold]
        TextSettings.HorzAlign = Center
        Text = 'Raio x de quadril'
      end
      object Label2: TLabel
        Tag = 1
        Align = Top
        AutoSize = True
        StyledSettings = [Family, FontColor]
        Padding.Top = 10.000000000000000000
        Padding.Bottom = 10.000000000000000000
        Margins.Top = 10.000000000000000000
        Margins.Bottom = 10.000000000000000000
        Position.X = 5.000000000000000000
        Position.Y = 84.000000000000000000
        Size.Width = 191.000000000000000000
        Size.Height = 24.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Size = 18.000000000000000000
        TextSettings.Font.Style = [fsBold]
        Text = 'Raio x de quadril '
        OnResize = Label2Resize
      end
      object Label4: TLabel
        Tag = 1
        Align = Top
        StyledSettings = [Family, FontColor]
        Padding.Top = 10.000000000000000000
        Padding.Bottom = 10.000000000000000000
        Margins.Top = 10.000000000000000000
        Margins.Bottom = 10.000000000000000000
        Position.X = 5.000000000000000000
        Position.Y = 47.000000000000000000
        Size.Width = 191.000000000000000000
        Size.Height = 17.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Size = 18.000000000000000000
        TextSettings.Font.Style = [fsBold]
        TextSettings.HorzAlign = Center
        Text = 'Raio x de quadril'
      end
      object Layout2: TLayout
        Tag = 1
        Align = Top
        Position.X = 5.000000000000000000
        Position.Y = 151.000000000000000000
        Size.Width = 191.000000000000000000
        Size.Height = 37.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 3
        OnResize = Layout2Resize
        object Label3: TLabel
          Align = FitLeft
          StyledSettings = [Family, FontColor]
          Margins.Top = 5.000000000000000000
          Margins.Bottom = 5.000000000000000000
          Position.Y = 5.000000000000000000
          Size.Width = 42.678131103515620000
          Size.Height = 27.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Size = 18.000000000000000000
          TextSettings.Font.Style = [fsBold]
          Text = 'De:'
        end
        object Label6: TLabel
          Align = Client
          StyledSettings = [Family, FontColor]
          Size.Width = 148.321868896484400000
          Size.Height = 37.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Size = 16.000000000000000000
          TextSettings.Font.Style = [fsBold]
          Text = 'R$ 10,00'
        end
      end
      object Layout3: TLayout
        Tag = 1
        Align = Top
        Position.X = 5.000000000000000000
        Position.Y = 118.000000000000000000
        Size.Width = 191.000000000000000000
        Size.Height = 33.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 4
        object Label7: TLabel
          Align = FitLeft
          StyledSettings = [Family, FontColor]
          Margins.Top = 5.000000000000000000
          Margins.Bottom = 5.000000000000000000
          Position.Y = 5.000000000000000000
          Size.Width = 43.193511962890620000
          Size.Height = 23.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Size = 18.000000000000000000
          TextSettings.Font.Style = [fsBold]
          Text = 'Por:'
        end
        object Label8: TLabel
          Align = Client
          StyledSettings = [Family, FontColor]
          Size.Width = 147.806488037109400000
          Size.Height = 33.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Size = 16.000000000000000000
          TextSettings.Font.Style = [fsBold]
          Text = 'R$ 10,00'
        end
      end
    end
    object Button1: TButton
      StyledSettings = [Family, FontColor]
      Position.X = 32.000000000000000000
      Position.Y = 320.000000000000000000
      Size.Width = 129.000000000000000000
      Size.Height = 41.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 0
      Text = 'Comprar'
      TextSettings.Font.Size = 20.000000000000000000
      TextSettings.Font.Style = [fsBold]
    end
    object Rectangle2: TRectangle
      Opacity = 0.800000011920928900
      Position.X = 156.000000000000000000
      Position.Y = -7.000000000000000000
      Size.Width = 50.000000000000000000
      Size.Height = 25.000000000000000000
      Size.PlatformDefault = False
      Stroke.Color = claChocolate
      object Label5: TLabel
        Align = Client
        StyledSettings = [Size, FontColor]
        Size.Width = 50.000000000000000000
        Size.Height = 25.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Segoe UI Semibold'
        TextSettings.Font.Style = [fsBold]
        TextSettings.HorzAlign = Center
        Text = '100%'
      end
    end
  end
end

【问题讨论】:

    标签: delphi firemonkey delphi-xe8


    【解决方案1】:

    您根本不需要更改TVertScrollBox。它会自动适应其内容。您只需更改TFlowLayout 的大小即可。在这种情况下,每当表单的大小发生变化时,都需要重新计算大小。

    所以你必须用Self.Resize替换VertScrollBox1.RealignContent,然后分配表单的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;
    

    【讨论】:

    • 谢谢,但是当我这样做时,滚动条永远不会显示。我有 ShowScrollBars=True
    • 我尝试使用所有组件的默认设置创建一个新应用程序,在运行时添加了一些基本框架并且它按预期工作,因此您可能有其他东西阻止了这种行为。
    • 我将发布我的 dfm 和我的 .pas。我看不出有什么问题。
    • 重要。我正在使用firemonkey,没有VCL。我认为与 firemonkey 合作有些不同
    • @Tiber 它不起作用。请使用我发布的单位和表格,看看这不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-01
    相关资源
    最近更新 更多