【问题标题】:Clear VertScrollBox in firemonkey application在 firemonkey 应用程序中清除 VertScrollBox
【发布时间】:2015-04-28 16:45:11
【问题描述】:

我有一个适用于 Android 手机的 firemonkey 应用程序,在 XE7、Win8 中。我有下面的 ShowMsg 程序将消息显示到 VertScrollBox 中。

我想清除 VertScrollBox,我正在尝试使用 ClearVertScrollBox 过程来执行此操作,但没有成功。

我在这里做错了什么?

procedure TForm1.ClearVertScrollBox;
var i:integer;
begin
  for i:=VSB.ControlsCount-1 downto 0 do
  begin
    if (VSB.Controls[i] is TCalloutRectangle) then begin
      VSB.Controls[i].DisposeOf;
      VSB.Controls[i]:=nil;
    end;
  end;
  VSB.Repaint;
end;

var VSB: TVertScrollBox;

procedure TForm1.ShowMsg(Title,GCMMsg,Msg:string);
var
  CR: TCalloutRectangle;
  L: TText;
begin
  CR := TCalloutRectangle.Create(Self);
  CR.Parent := VSB;
  CR.Align := TAlignLayout.alTop;
  CR.CalloutPosition := TCalloutPosition.cpLeft;
  CR.Margins.Top := 10;
  CR.Margins.Bottom := 10;
  CR.Margins.Right := 5;
  CR.Height := 75;

  L := TText.Create(Self);
  L.Parent := CR;
  L.Align := TAlignLayout.alTop;
  L.Text := Title;
  L.Margins.Left := 15;
  L.Margins.Right := 5;
  L.Width := CR.Width-20;
  L.Height:=20;

  L := TText.Create(Self);
  L.Parent := CR;
  L.Align := TAlignLayout.alClient;
  L.Text := GCMMsg;//GCMMsg+':'+Msg;
  L.Margins.Left := 15;
  L.Margins.Right := 5;
  L.Width := CR.Width-20;

  L.WordWrap := True;
  L.AutoSize := True;
end;

【问题讨论】:

    标签: android delphi mobile firemonkey


    【解决方案1】:

    您的ClearVertScrollBox 只需要一些调整,您只需通过它的控件并检查其中一个是否为TCalloutRectangleTVertScrollBox 不会简单地将您的TCalloutRectangle 存储在控制节点的第一棵树中.

    TVertScrollBox 有一个 TScrollContent,这将是您存储控件的控件

    这样就够了

    var
        I,II : Integer; 
    begin
    for i:= VSB.ControlsCount-1 downto 0 do
        begin
            if VSB.Controls[I].ClassType = TScrollContent then
            begin
                for II := VSB.Controls[I].ControlsCount-1 downto 0 do
                begin
                    if VSB.Controls[I].Controls[II].ClassType = TCalloutRectangle then
                    begin
                        VSB.Controls[I].Controls[II].Parent := nil;
                    end;
                end;
            end;
        end; 
    end;
    

    在创建 TCalloutRectangle 时也会造成内存泄漏

    您正在使用所有者创建所有对象,更具体地说,您使用 Self 关键字将表单设置为所有者,因此即使您“可视地”将其从 TVertScrollBox 中删除,该对象仍然是拥有的通过您的表单,对象引用计数永远不会达到 0,这意味着 ARC 将无法释放它。

    而不是像这样使用所有者创建您的对象:

    CR := TCalloutRectangle.Create(Self);

    这样做

    CR := TCalloutRectangle.Create(nil);

    如果您已经将其分配给父级,则不需要将其分配给所有者,请为您的 TCalloutRectangleTText(我假设它们是 TLabels?)对象执行此操作

    如果您只使用父对象创建对象并使用新代码将它们从TVertScrollBox 中删除,您将破坏对这些对象的所有引用并释放它们,这意味着不需要DisposeOf 调用

    【讨论】:

      【解决方案2】:

      我使用下面的代码来清除我的滚动框,就我而言,我只想删除列表中的所有项目,而不是特定的项目。

      unit uScrollBoxHelper;
      
      interface
      
      uses FMX.Layouts;
      
      type
        TVertScrollBoxHelper = class helper for TVertScrollBox
        public
          procedure Clear;
        end;
      
        THorzScrollBoxHelper = class helper for THorzScrollBox
        public
          procedure Clear;
        end;
      
      implementation
      
      { TVertScrollBoxHelper }
      
      procedure TVertScrollBoxHelper.Clear;
      var
        I: Integer;
      begin
        for I := self.Content.ChildrenCount - 1 downto 0 do
          self.Content.Children.Items[I].DisposeOf;
      end;
      
      { THorzScrollBoxHelper }
      
      procedure THorzScrollBoxHelper.Clear;
      var
        I: Integer;
      begin
        for I := self.Content.ChildrenCount - 1 downto 0 do
          self.Content.Children.Items[I].DisposeOf;
      end;
      
      end.
      

      然后,当我想在表单中使用代码时,我只需这样做:

        VertScrollBox1.BeginUpdate;
        VertScrollBox1.Clear;
      ...
        VertScrollBox1.EndUpdate;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-29
        相关资源
        最近更新 更多