You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi中无法从TVertScrollBox移除子控件求助

解决FMX VertScrollBox删除除首个矩形外所有控件的问题

首先咱们先拆解你遇到的问题:反向循环删除控件却没生效,大概率和控件的Parent设置以及删除时是否正确释放对象有关,咱们一步步来搞定:

第一步:先把添加克隆矩形的逻辑补严谨

你添加矩形的代码里,Clone(VertScrollBox)理论上已经把新克隆的矩形Parent设为VertScrollBox了,但为了避免克隆过程中的意外,最好显式设置一下,同时给克隆的矩形设置位置避免重叠,方便后续验证删除效果:

VertScrollBox.BeginUpdate;
try
  for i := 0 to 19 do begin
    // 克隆模板矩形并指定父容器
    Rectangle:= TRectangle(RectangleTemplate.Clone(VertScrollBox));
    // 显式设置Parent,确保控件归属正确
    Rectangle.Parent := VertScrollBox;
    // 给每个克隆矩形设置垂直位置,避免堆叠在一起
    Rectangle.Top := RectangleTemplate.Top + (Rectangle.Height + 10) * i;
  end;
finally
  // 确保EndUpdate一定会执行,避免控件状态异常
  VertScrollBox.EndUpdate;
end;

第二步:修正删除控件的代码

你的反向循环思路是对的,但FMX的RemoveObject只是把控件从容器的Children列表中移除,并不会自动释放控件内存——如果只调用RemoveObject,控件可能还留在内存里,甚至视觉上没消失。正确的做法是移除后立即释放:

VertScrollBox.BeginUpdate;
try
  // 从最后一个控件反向循环到第2个(索引1),避免正向循环时索引偏移
  for j := VertScrollBox.ChildrenCount - 1 downto 1 do begin
    if VertScrollBox.Children[j] is TRectangle then begin
      // 先获取要删除的控件引用
      var RectToDelete := TRectangle(VertScrollBox.Children[j]);
      // 从容器中移除控件
      VertScrollBox.RemoveObject(RectToDelete);
      // 释放控件内存,避免泄漏
      RectToDelete.Free;
    end;
  end;
finally
  VertScrollBox.EndUpdate;
end;

额外要注意的细节

  1. 确认首个矩形的索引:要确保Children[0]确实是你想保留的RectangleTemplate,如果模板矩形本身不在VertScrollBox的Children里(比如设计时放在ScrollBox外),那需要调整循环的起始索引,确保保留正确的目标控件。
  2. 必须释放控件:只移除不释放会造成内存泄漏,长期运行会导致程序性能下降。
  3. 始终用BeginUpdate/EndUpdate:无论添加还是删除控件,这对方法都能避免控件频繁刷新,提升操作的流畅度。

这样修改后,点击删除按钮就能正确移除除第一个矩形外的所有克隆控件了。

内容的提问来源于stack exchange,提问作者Raffaele Rossi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:28:01