Delphi 从滚动框中删除控件
我正在使用myScrollBox.AddObject动态地(在运行时)将控件添加到TScrollBox中 现在我需要删除我添加的所有控件以放置新控件 我尝试了myScrollBox.Controls.Clear,但在调用该函数后,我添加的任何控件都不会显示 (警告:我是delphi和Firemonkey的新手) 更新1 下面是我添加对象的方式(这只是一个测试函数) 有趣的是,如果我在count上放置一个断点:=scbTaskVariables.ControlsCount 我可以看到,对于第一个控件,ControlScont从0变为1,对于其他控件,它保持为1 更新2Delphi 从滚动框中删除控件,delphi,firemonkey,Delphi,Firemonkey,我正在使用myScrollBox.AddObject动态地(在运行时)将控件添加到TScrollBox中 现在我需要删除我添加的所有控件以放置新控件 我尝试了myScrollBox.Controls.Clear,但在调用该函数后,我添加的任何控件都不会显示 (警告:我是delphi和Firemonkey的新手) 更新1 下面是我添加对象的方式(这只是一个测试函数) 有趣的是,如果我在count上放置一个断点:=scbTaskVariables.ControlsCount 我可以看到,对于第一个控
我提交了。与
AddObject
相反的是RemoveObject
。为每个要删除的子对象调用ScrollBox.RemoveObject(aChildObject)
另一种方法是设置子对象的Parent
属性。将其设置为ScrollBox
以添加它。将其设置为nil
将其删除。这可以与AddObject
和RemoveObject
互换。你可以用任何一种方法
但是,当您尝试这样做时,正如您所说的,如果您先前删除了控件,则添加新控件的尝试将失败。这似乎是一个bug。请提交质量控制报告
我在XE6上测试。与
AddObject
相反的是RemoveObject
。为每个要删除的子对象调用ScrollBox.RemoveObject(aChildObject)
另一种方法是设置子对象的Parent
属性。将其设置为ScrollBox
以添加它。将其设置为nil
将其删除。这可以与AddObject
和RemoveObject
互换。你可以用任何一种方法
但是,当您尝试这样做时,正如您所说的,如果您先前删除了控件,则添加新控件的尝试将失败。这似乎是一个bug。请提交质量控制报告
我在XE6上进行了测试。我添加了这一点作为答案,但由于FMX中存在缺陷,因此在现阶段应将其视为一种解决方法 我花了一些时间来解决您关于删除按钮的问题,但也试图了解更多有关该错误的信息。大卫很快发现了这一点,并展示了他的经验 我的两个发现是:(1)AddObect()似乎不适用于按钮,出于某种原因,它们不被视为“对象”,而是“组件”。(2) 我还发现,使用“scrollBox”作为其所有者创建btn1有助于获得适当的结果 我使用了1个TScrollbox、2个T按钮和4个T标签。按钮保留默认名称,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”过程就相当简单了
使用FindComponent行完成了这个任务
按F1键并在URL框中键入链接;我发现这些很有趣,尤其是看到了如何在VCL和FMX中派生TButton
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
我添加了这一点作为答案,但由于FMX中存在缺陷,因此在现阶段应将其视为一种解决方法 我花了一些时间来解决您关于删除按钮的问题,但也试图了解更多有关该错误的信息。大卫很快发现了这一点,并展示了他的经验 我的两个发现是:(1)AddObect()似乎不适用于按钮,出于某种原因,它们不被视为“对象”,而是“组件”。(2) 我还发现,使用“scrollBox”作为其所有者创建btn1有助于获得适当的结果 我使用了1个TScrollbox、2个T按钮和4个T标签。按钮保留默认名称,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”过程就相当简单了
使用FindComponent行完成了这个任务
按F1键并在URL框中键入链接;我发现这些很有趣,尤其是看到了如何在VCL和FMX中派生TButton
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
默认情况下,TScrollBox有一个类型为TScrollContent的组件,负责显示其他组件。因此,如果我们删除他,那么将永远不会显示任何内容 我创建了这个小函数来移除TScrollBox中的所有组件(TScrollContent除外):
此方法可以通过递归性来改进默认情况下,TScrollBox有1个组件,属于TScrollContent类型,负责显示其他组件。因此,如果我们删除他,那么将永远不会显示任何内容 我创建了这个小函数来移除TScrollBox中的所有组件(TScrollContent除外): 可通过递归性改进此方法尝试以下方法:
myScrollBox.Content.DeleteChildren;
尝试:
myScrollBox.Content.DeleteChildren;
我尝试了你建议的迭代,但我仍然有同样的问题。只要我取下控制装置。有趣的是,我添加了100 t按钮,但ControlsCount值是2??A可以看到scrollbox中的100个按钮,如果我单击它们时触发了单击事件。这可能是我首先添加它们的方式。我编辑了这个问题,以包括如何首先创建控件。也许你能看到有什么不对劲,这是个错误。您可以将代码很好地用于面板和其他容器。只是不要滚动框。请提交一份质量控制报告。质量控制编号是多少?我尝试了你建议的迭代,但我仍然有相同的问题。只要我取下控制装置。有趣的是,我添加了100 t按钮,但ControlsCount值是2??A可以看到scrollbox中的100个按钮,当我单击它们时,单击事件会被触发。这可能是我在