从滚动框中删除控件

时间:2014-06-11 18:22:19

标签: delphi firemonkey

我是动态的(在运行时)使用myScrollBox.AddObject将控件添加到TScrollBox

现在我需要删除我添加的所有控件以添加新控件。

我尝试了myScrollBox.Controls.Clear但是在我调用该函数后,我添加的任何控件都没有显示出来。

(警告:我是delphi和Firemonkey的新手)

更新1

以下是我添加对象的方法(这只是一个测试函数)

procedure TMainForm.TaskDetailsAdd;
var
  btn1 : TButton;
  intI : Integer;
  count: Integer;

begin
  scbTaskVariables.BeginUpdate;

  count    := 0;
  for intI := 0 to 100 do
    begin
      btn1            := TButton.Create(self);
      btn1.Text       := 'Salut ' + IntToStr(intI);
      btn1.Parent     := scbTaskVariables;
      btn1.OnClick    := Button1Click;
      btn1.Tag        := intI * 10;
      btn1.Position.Y := intI * 50;
      btn1.Position.X := intI * 15;
      scbTaskVariables.AddObject(btn1);
      count := scbTaskVariables.ControlsCount;
    end;
  scbTaskVariables.EndUpdate;
end;

有趣的是,如果我在count上放置一个断点:= scbTaskVariables.ControlsCount 我可以看到ControlsCount从第一个控件的0变为1,然后在其他控件中保持为1。

更新2

我提交了QC#125440

4 个答案:

答案 0 :(得分:3)

AddObject的倒数是RemoveObject。为要删除的每个子对象调用ScrollBox.RemoveObject(aChildObject)

另一种方法是设置子对象的Parent属性。将其设置为ScrollBox以添加它。将其设置为nil以将其删除。这可与AddObjectRemoveObject互换。你可以这样做。


但是,当您尝试执行此操作时,正如您所说,如果您之前删除了控件,则尝试添加新控件会失败。这似乎是一个错误。请提交质量控制报告。

我在XE6上测试过。

答案 1 :(得分:2)

我已将此添加为答案,但由于FMX中存在错误,因此在此阶段应将其视为解决方法。

我花了一些时间来解决关于删除按钮的问题,还试图找出有关该错误的更多信息。大卫很快发现了这一点并展示了他的经历。

我的两个发现是(1)AddObect()似乎不适用于按钮,出于某种原因,它们不会被视为"对象"但作为"组件"。 (2)我还发现使用" scrollBox"创建btn1。因为它的主人帮助取得了足够的成果。

我使用了1 x TScrollbox,2 x TButton和4 x TLabel。按钮保留默认名称,TScrollBox保留默认名称。所以你可以复制和粘贴。 btn1是一个私有变量及其程序。

procedure TMainForm.TaskDetailsAdd;
var
  intI : Integer;
begin
  label1.Text := IntToStr(scbTaskVariables.ComponentCount);
      // Initial count = 1, Probably the scroll box.

if scbTaskVariables.ComponentCount >1 then
  TaskDetailsDel; // Don't create Buttons with same Name if already exists.

scbTaskVariables.BeginUpdate;
  for intI := 0 to 99 do
  begin
    Sleep(20); //Keeps the "Pressed Button" active to prove it is working
      btn1              := TButton.Create(scbTaskVariables);
      btn1.Parent       := scbTaskVariables;
      btn1.Position.Y   := intI * 50;
      btn1.Position.X   := intI * 15;
      btn1.Tag          := intI * 10;
      btn1.TabOrder     := 10 + intI;
      btn1.Name         := 'MyBtn' + IntToStr(intI);
      btn1.Text         := 'Salut ' + IntToStr(intI);
      btn1.OnClick      := Button1Click;

      if btn1.IsChild(scbTaskVariables) = true then
        Label2.Text := 'True'
      else               // All this, proves buttons not seen as children.
        Label2.Text := 'False';

      scbTaskVariables.AddObject(btn1);
                // AddObject() taken out as button is not seen as "FmxObject"
  end;
scbTaskVariables.EndUpdate;

  Label3.Text := IntToStr(scbTaskVariables.ComponentCount);
                // Count now all created (includes ScrollBox).
  Label4.Text := IntToStr(scbTaskVariables.ControlsCount);
end;

" TaskDetailsDel"一旦我确定我真的在处理"组件"

procedure TMainForm.TaskDetailsDel;
var
  intI : Integer;
  count: Integer;
begin
  label1.Text := '';
  label2.Text := '';
  label3.Text := '';
  label4.Text := '';

  for intI := 0 to 99 do
    begin
      Sleep(20);   //Keeps the "Pressed Button" active to prove it is working
      btn1 := TButton(scbTaskVariables.FindComponent('MyBtn' + IntToStr(intI)));
        btn1.Parent := Nil;
          FreeAndNil(btn1);
    end;
  Count := scbTaskVariables.ComponentCount;
  Label1.Text := IntToStr(Count);
end;

使用FindComponent行就可以了。

按F1键并在URL框中键入链接;我发现这些很有趣,尤其是看看TButton是如何在VCL和FMX中得出的。

ms-help://embarcadero.rs_xe3/libraries/Vcl.StdCtrls.TButton.html
ms-help://embarcadero.rs_xe3/libraries/FMX.Controls.TButton.html
ms-help://embarcadero.rs_xe3/libraries/FMX.Types.TStyledControl.html
ms-help://embarcadero.rs_xe3/rad/Objects,_Components,_and_Controls.html
ms-help://embarcadero.rs_xe3/libraries/FMX.Types.TFmxObject.AddObject.html

答案 2 :(得分:0)

默认情况下,TScrollBox具有1个类型为TScrollContent的组件,该组件负责显示其他组件。因此,如果我们删除他,那么将永远不会显示任何内容。

我创建了这个小函数,用于TScrollBox内的RemoveAllComponents(期望TScrollContent):

procedure RemoveAllComponentsScrollBox(ScrollBox : TScrollBox);
var i : integer; Obj : TFmxObject;
begin
  for I := ScrollBox.ComponentCount-1 downto 0 do
  begin
    if ((ScrollBox.Components[i] is TFmxObject) and not (ScrollBox.Components[i] is TScrollContent)) then
    begin
      Obj:=TFmxObject(ScrollBox.Components[i]);
      Obj.Parent:=nil;
      FreeAndNil(Obj);
    end;
  end;
end;

此方法可以通过递归进行改进

答案 3 :(得分:-1)

尝试:

myScrollBox.Content.DeleteChildren;