1

I currently create a two TLabels and a TEdit dynamically, naming them LblDesc+i, EdtAmount+i and LblUnit+i - Where i is an integer that I iterate up by one each time I add those 3 elements. The data in the elements are just for simulation purposes. My problem now is deleting the three objects. Ive tried with free and FreeAndNil, no luck at all. Any help is greatly appreciated.

procedure TForm1.BtnAddClick(Sender: TObject);
begin
  LblDesc := TLabel.Create(Self);
  LblDesc.Caption := 'Item '+IntToStr(i);
  LblDesc.Name := 'LblDesc'+IntToStr(i);
  LblDesc.Left := 16;
  LblDesc.Top := 30 + i*30;
  LblDesc.Width := 100;
  LblDesc.Height := 25;
  LblDesc.Parent := Self;

  EdtAmount := TEdit.Create(Self);
  EdtAmount.Text := IntToStr(i);
  EdtAmount.Name := 'EdtAmount'+IntToStr(i);
  EdtAmount.Left := 105;
  EdtAmount.Top := 27 + i*30;
  EdtAmount.Width := 60;
  EdtAmount.Height := 25;
  EdtAmount.Parent := Self;

  LblUnit := TLabel.Create(Self);
  LblUnit.Caption := 'Kg';
  LblUnit.Name := 'LblUnit'+IntToStr(i);
  LblUnit.Left := 170;
  LblUnit.Top := 30 + i*30;
  LblUnit.Width := 50;
  LblUnit.Height := 25;
  LblUnit.Parent := Self;

  i := i+1;
end;

procedure TForm1.BtnRemoveClick(Sender: TObject);
begin
  //Delete

end;
Ken White
  • 123,280
  • 14
  • 225
  • 444
H4rdstyler
  • 71
  • 1
  • 11
  • 1
    What do you mean by "no luck"? What happens/doesn't happen? Anyway you need to show the code that you're actually trying to use to remove the components. – MartynA Feb 17 '16 at 10:39
  • 1
    Welcome to StackOverflow. Please show how exactly you tried to delete these controls. In any case, you could either keep the references of created controls, or retrieve them by name with [`FindComponent`](http://docwiki.embarcadero.com/Libraries/XE7/en/System.Classes.TComponent.FindComponent) later. – Free Consulting Feb 17 '16 at 10:41
  • I reverted your last edit. If you want to show the code that ended up working, post it as an answer in the space below (headed *Your Answer*) where it belongs. Answering your own question is totally acceptable here. – Ken White Feb 17 '16 at 13:49

3 Answers3

4

In the past I had issues related to the deletion of some component that I've solved setting the parent's component to nil but it should be no longer the case since TControl's destructor - if called - already does the job.

The component should be removed by simply freeing it.

LblUnit.Free;

If you need to find the component by its name, use System.Classes.TComponent.FindComponent or iterate on the Components list.

for i := ComponentCount-1 downto 0 do begin
  if Components[i].Name = 'LblUnit'+IntToStr(i) then begin
    //TControl(Components[i]).Parent := nil; {uncomment if you have the same issue I've had}
    Components[i].Free;
  end;
  . . .  
end;

EDIT

If the index i used for the component's name construction 'LblUnit'+IntToStr(i) doesn't lie in the range [0..ComponentCount-1], the index has to be modified accordingly.

fantaghirocco
  • 4,761
  • 6
  • 38
  • 48
0

To delete dynamically created component, you must have valid reference to it.

You can organize own array or list to keep your objects, or use existing lists, for example - Form.Components[] which holds objects whose owner is Form.

In the second case you have to find needed objects with FindComponent by name or walk through Components[] and search for component with some feature (Name, class type, Tag etc)

MBo
  • 77,366
  • 5
  • 53
  • 86
0

The answer that ended up working was this:

procedure TForm1.BtnRemoveClick(Sender: TObject);
var
  j: Integer;

begin
  for j := ComponentCount-1 downto 0 do begin
    if Components[j].Name = 'LblDesc'+IntToStr(i-1) then begin
      TControl(Components[j]).Parent := nil;
      Components[j].Free;
    end;
  end;
end;
H4rdstyler
  • 71
  • 1
  • 11
  • 1
    There is no need to set Parent to nil – MBo Feb 17 '16 at 16:46
  • You are better off keeping your own array/list of labels that you create, and then you can loop through that when needed. You *can* use the `Owner`'s `Components[]` property or the `Parent`'s `Controls[]` property to manage that for you, but it is overkill considering that other controls are also in those same lists. Better to isolate your desired controls in their own list, your code will be cleaner and safer for it. – Remy Lebeau Feb 17 '16 at 18:21