Reputation: 3258
This is probably a stupid question, but my brain is just cooked enough I think I'm going to use one of my "lifelines" to see if I can get some help from my stack overflow friends. ;)
I need to delete all occurrences of a particular component type on my main form (some of them are inside panels or tabsheets, but all on and owned by the same form). Here's what I have now:
for i := 0 to frmMain.ComponentCount - 1 do
begin
if frmMain.Components[i] is TMyClass then frmMain.Components[i].Destroy;
end;
The problem is (and I knew it would be before I compiled it) that once I destroy the component, the form's component list re-indexes and I end up out of bounds.
What's the best way to solve this? I thought about adding the "found" components to a standalone array, and then walk through that after this loop to delete them, which I think will work.... but is that the best approach?
TIA
UPDATE:
You guys rock. Thanks. : )
Upvotes: 12
Views: 16617
Reputation: 1
For Fine Contrle in form or panel can use this code
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;
Upvotes: -2
Reputation: 2093
It may not happen in your case, but the if frmMain.Components[i] is TMyClass
check will also return true for descendant classes of TMyClass
. If you are really looking for the removal of one specific class, you may need to add an extra check of the ClassName
.
Upvotes: 2
Reputation: 1
If you need to check & destroy a named known component Use
If YourComponent <> Nil Then
YourComponent.Free;
Upvotes: -3
Reputation: 12898
The same solution with a while-loop:
i := 0;
while i < frmMain.ComponentCount do
begin
if frmMain.Components[i] is TMyClass then
frmMain.Components[i].Free
else
inc(i);
end;
Upvotes: 1
Reputation: 13454
You're nearly right. Your loop should look like
for i := frmMain.ComponentCount - 1 downto 0 do
begin
if frmMain.Components[i] is TMyClass then
frmMain.Components[i].Free;
end;
This way the call to the function "frmMain.ComponentCount" gets done at the beginning and not again.
You should also call Free as above, not Destroy - I can't remember why at the moment. Bri
Upvotes: 28
Reputation: 2237
Start at the top and work backwards.
viz:
for i := frmMain.ComponentCount - 1 downto 0 do
begin
if frmMain.Components[i] is TMyClass then frmMain.Components[i].Free;
end;
Call free instead of Destroy. Free calls Destroy after checking for a valid reference.
Upvotes: 10