开发者

Delphi - Deleting runtime generated buttons from TPanel

I have several TPanels that are populated with buttons at runtime. However the code below that i use to free my buttons from their parent panels sometimes generates access violation errors.

procedure TfrmTakeOrder.FreeItemButtons(buttons : array of TButton);
var
  cnt,i : integer;
begin

  for i := 0 to gridLayoutItems.ControlCount - 1 do
    begin
      buttons[i].Free;
      buttons[i] := nil;
    end;

end;

Is there a better way to do this?Please keep in mind that o开发者_运维百科ther Panels have buttons too and I would like to have a "localised" freeing of the buttons that wount intefer with other panels.


It looks to me like you are trying to remove all buttons from a TPanel and that panel only contains buttons.

Try this:

while gridLayoutItems.ControlCount > 0 do
  gridLayoutItems.Controls[0].Free;


If:

  • that panel has only buttons, and
  • your array has all the buttons on several panels.

Then use:

var
  I: Integer;
  Button: TControl;
begin
  for I := GridLayoutItems.ControlCount - 1 downto 0 do
  begin
    Button := GridLayoutItems.Controls[I];
    Button.Free;
    { Find the index of Button in the Buttons array };
    { Erase that item from the array };
  end;
end;

But in this scenario, it is much more handy to have a TList for Buttons instead of an array, becasue then the code becomes:

var
  I: Integer;
  Button: TControl;
begin
  for I := GridLayoutItems.ControlCount - 1 downto 0 do
  begin
    Button := GridLayoutItems.Controls[I];
    Button.Free;
    Buttons.Remove(Button);
  end;
end;


Maybe it would be better to use Length(buttons) - 1 instead of gridLayoutItems.ControlCount - 1 which could be different.


You have to correct the bounds of your for-loop like the other answers state. One more thing:

How do you create the buttons? If you create the buttons with an owner, i.e.

buttons [i] := TButton.Create (Panel);

then you must not free them manually. The owner takes care of that. In this case just use

buttons [i] := TButton.Create (nil);


Yes. Use for i := Low(buttons) to high(Buttons) do


In more recent versions of Delphi (like XE5), Free does not exist any more. I solved the problem using Destroy instead of Free.


If you want to free only buttons from parent panel:

var i : integer
begin
i := 0;
while Panel1.ControlCount > i do
  if Panel1.Controls[i] is TButton then
     Panel1.Controls[i].Free
  else inc(i);
end;


you can use this code

for i := 0 to ComponentCount-1 do
 begin
  if ( Components[ i ] is TPanel ) then
  (Components[ i ] as TPanel ).free;
 end;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜