Delete TLabel in Delphi

963 views Asked by At

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;
3

There are 3 answers

17
fantaghirocco On BEST ANSWER

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.

2
H4rdstyler On

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;
0
MBo On

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)