2011-06-09 146 views
4

刪除運行時生成按鈕我有被填充在運行時按鈕幾個TPanels。然而,我用來從他們的父面板釋放我的按鈕的代碼有時會產生訪問衝突錯誤。德爾福 - 從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; 

有沒有更好的方式來做到這一點?請記住,其他各小組有按鈕也和我想有wount intefer與其他面板按鈕的「本地化」釋放。

回答

7

它看起來像你對我正試圖刪除從TPanel所有按鈕和麪板只包含按鈕。

試試這個:

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

這已經爲我做了訣竅:) – davykiash 2011-06-09 11:21:50

+2

請確保你放棄了你自己的按鈕陣列。否則,如果您嘗試使用它們,則會引用已釋放陣列中的內存並導致訪問衝突。 – jpfollenius 2011-06-09 12:10:32

1

也許這將是更好地使用Length(buttons) - 1代替gridLayoutItems.ControlCount - 1這可能是不同的。

+0

不'可能',確切地說,因爲即使'gridLayoutItems'碰巧只包含這些按鈕,釋放按鈕使'ControlCount'減少:您將停下來!並且不要麻煩設置'buttons [i]:= nil'',因爲'buttons'是該函數的一個參數,當函數返回時新值將丟失。 – 2011-06-09 10:55:47

+0

我不知道動態數組是通過複製而不是引用傳遞的。好點子。 – 2011-06-09 11:26:36

+2

@Cosmin,你不會停下來。 for循環邊界在循環開始時計算一次;循環運行時不會重新評估它們。 – 2011-06-09 13:38:55

0

是。使用for i := Low(buttons) to high(Buttons) do

+0

我有幾個TPanels的form.Wount這也得到了其他面板中的按鈕的計數? – davykiash 2011-06-09 10:57:51

+0

如果您存儲在一個陣列中的按鈕它當然會從所有面板中刪除按鈕。 – jpfollenius 2011-06-09 10:59:20

1

你必須糾正你的for循環像其他答案國家的邊界​​。還有一兩件事:

如何創建按鈕?如果創建一個所有者的按鈕,即

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

那麼你一定不能手動釋放它們。業主照顧。在這種情況下,只需使用

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

完成'按鈕[i]:= TButton.Create(Whatever)'是完全可以的,然後釋放按鈕。當按鈕被釋放時,它的所有者會收到一條通知,將其從它擁有的對象列表中刪除,以便它不會再次釋放它。也就是說,如果按鈕被釋放,因爲表單需要在運行時進行更改:如果釋放按鈕的代碼是從表單的析構函數調用的,那麼這是無意義的,並且可能是危險的。 – 2011-06-09 11:00:04

+0

@Cosmin:謝謝你的提醒,我不知道。始終認爲它是「所有者」或手動「免費」。 – jpfollenius 2011-06-09 11:01:56

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; 

但在這種情況下,它是更方便的有按鈕,而不是一個數組從TList,becasue那麼代碼變爲:

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

在最新版本的Delphi(如XE5)中,Free不再存在。我用Destroy而不是Free解決了這個問題。