我有几个在运行时用按钮填充的TPanel。但是,我用来从父面板中释放按钮的代码有时会产生访问冲突错误。
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;
有更好的方法吗?请记住,其他面板也有按钮,我希望“本地化”释放与其他面板密切相关的按钮。
答案 0 :(得分:7)
在我看来,您正试图从TPanel中删除所有按钮,并且该面板仅包含按钮。
试试这个:
while gridLayoutItems.ControlCount > 0 do
gridLayoutItems.Controls[0].Free;
答案 1 :(得分:3)
如果:
然后使用:
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;
但是在这种情况下,为Buttons而不是数组创建一个TList会更方便,因为代码变成了:
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;
答案 2 :(得分:1)
也许最好使用Length(buttons) - 1
而不是gridLayoutItems.ControlCount - 1
,这可能会有所不同。
答案 3 :(得分:1)
你必须像其他答案状态一样纠正你的for循环的界限。还有一件事:
如何创建按钮?如果您使用所有者创建按钮,即
buttons [i] := TButton.Create (Panel);
然后你不能手动释放它们。业主负责照顾。在这种情况下,只需使用
buttons [i] := TButton.Create (nil);
答案 4 :(得分:0)
是。使用for i := Low(buttons) to high(Buttons) do
答案 5 :(得分:0)
在最新版本的Delphi(如XE5)中,Free不再存在。我使用Destroy而不是Free解决了这个问题。
答案 6 :(得分:0)
如果您只想从父面板中释放按钮:
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;
答案 7 :(得分:0)
您可以使用此代码
for i := 0 to ComponentCount-1 do
begin
if ( Components[ i ] is TPanel ) then
(Components[ i ] as TPanel ).free;
end;