删除表单上某个类的所有组件(Delphi)

时间:2009-02-11 22:48:51

标签: delphi forms components

这可能是一个愚蠢的问题,但我的大脑已经足够熟了我想我将使用我的一条“生命线”来看看我是否可以从我的堆栈溢出的朋友那里得到一些帮助。 ;)

我需要删除主窗体上所有特定组件类型的出现(其中一些是在面板或标签页内,但全部在同一个窗体上并由同一个窗体拥有)。这就是我现在所拥有的:

for i := 0 to frmMain.ComponentCount - 1 do  
  begin  
    if frmMain.Components[i] is TMyClass then frmMain.Components[i].Destroy;  
  end;    

问题是(并且我知道它将在我编译之前),一旦我销毁组件,表单的组件列表重新索引并且我最终超出范围。

解决这个问题的最佳方法是什么?我想过将“找到的”组件添加到一个独立的数组中,然后在这个循环之后逐步删除它们,我认为它们会起作用....但这是最好的方法吗?

TIA


更新:

你们摇滚。谢谢。 :)

6 个答案:

答案 0 :(得分:27)

你几乎是对的。你的循环应该看起来像

for i := frmMain.ComponentCount - 1 downto 0 do
begin
  if frmMain.Components[i] is TMyClass then
    frmMain.Components[i].Free;
end;

这样对函数“frmMain.ComponentCount”的调用在开始时完成,而不是再次完成。

你也应该如上所述召唤Free,而不是Destroy - 我现在不记得为什么。 BRI

答案 1 :(得分:10)

从顶部开始向后工作。

即:

for i := frmMain.ComponentCount - 1 downto 0 do
begin
  if frmMain.Components[i] is TMyClass then frmMain.Components[i].Free;
end; 

免费呼叫而不是毁灭。免费电话在检查有效参考后销毁。

答案 2 :(得分:2)

使用while循环的相同解决方案:

i := 0;
while i < frmMain.ComponentCount do
begin
  if frmMain.Components[i] is TMyClass then
    frmMain.Components[i].Free 
  else
    inc(i);
end;

答案 3 :(得分:2)

在您的情况下可能不会发生,但对于if frmMain.Components[i] is TMyClass的后代类,TMyClass检查也将返回true。如果您真的想要删除一个特定的类,则可能需要额外检查ClassName

答案 4 :(得分:-2)

对于窗体或面板中的精细控制,可以使用此代码

var

 i:Integer;

begin

for i := 0 to Panel1.ControlCount - 1 do

  begin

    if Panel1.Controls[i] is TEdit then
       Tedit(Panel1.Controls[i]).text := '';

  end;

答案 5 :(得分:-3)

如果你需要检查&amp;销毁已命名的已知组件 使用

If YourComponent <> Nil Then
  YourComponent.Free;