这可能是一个愚蠢的问题,但我的大脑已经足够熟了我想我将使用我的一条“生命线”来看看我是否可以从我的堆栈溢出的朋友那里得到一些帮助。 ;)
我需要删除主窗体上所有特定组件类型的出现(其中一些是在面板或标签页内,但全部在同一个窗体上并由同一个窗体拥有)。这就是我现在所拥有的:
for i := 0 to frmMain.ComponentCount - 1 do
begin
if frmMain.Components[i] is TMyClass then frmMain.Components[i].Destroy;
end;
问题是(并且我知道它将在我编译之前),一旦我销毁组件,表单的组件列表重新索引并且我最终超出范围。
解决这个问题的最佳方法是什么?我想过将“找到的”组件添加到一个独立的数组中,然后在这个循环之后逐步删除它们,我认为它们会起作用....但这是最好的方法吗?
TIA
更新:
你们摇滚。谢谢。 :)
答案 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;