如何釋放在 Panel 裏所建立的動態按鈕元件 |
答題得分者是:老大仔
|
kending
一般會員 發表:4 回覆:6 積分:2 註冊:2010-08-04 發送簡訊給我 |
我在 FORM 裏有放一個 Panel 元件 ,而 Panel 裏會依使用者輸入的值,動態產生 N 個 TBitBtn元件
請問我要怎樣才能釋放 Panel 裏的按鈕元件呢 ? 動態數量的元件 這樣的程式都會出錯· procedure TCabinetListForm.Action2Execute(Sender: TObject); var i : Integer; begin for I := 0 to Panel1.ControlCount - 1 do Panel1.Controls[i].Free; end; Error Message : List Index out of Bounds(30) 請問高手,我要怎麼去釋放元件呢 ? |
Jasonwong
版主 發表:49 回覆:931 積分:581 註冊:2006-10-27 發送簡訊給我 |
|
kending
一般會員 發表:4 回覆:6 積分:2 註冊:2010-08-04 發送簡訊給我 |
謝謝版主的回覆,但還是遇到相同的問題, 我是新手所以遇到很多小弟不懂的問題. 如下是我繼承 TBitBtn Class 的元件 Called : TCemeteryBitBtn unit CemeteryUnit; interface uses Windows, Classes, Graphics, Forms, Controls, StdCtrls, Buttons, ExtCtrls; type TCemeteryBitBtn = class(TBitBtn) private { Private declarations } public { Public declarations } TowerID: String; FloorID: String; DirectionID: String; CabinetNo : String; BoxNo : String; end; var CemeteryBitBtn: TCemeteryBitBtn; implementation end. ======================================= 產生按鈕的程式 // Cabinet Detail SQL2 := 'Select * from CabinetDetail ' ' where TowerID = "' VTowerID '" and FloorID = "' vFloorID '" and ' 'DirectionID = "' vDirectionID '" and CabinetNo = ' intToStr(vCabinetNo) ' order by BoxNo asc '; with ADOQueryOfDetail do begin try Active := False; SQL.Clear; SQL.Add(SQL2); ExecSQL; Active := True; x := 1 ; y := 1 ; While not Eof Do begin btn := TCemeteryBitBtn.Create(self); btn.TowerID := FieldByName('TowerID').AsString; btn.FloorID := FieldByName('FloorID').AsString; btn.DirectionID := FieldByName('DirectionID').AsString; btn.CabinetNo := FieldByName('CabinetNo').AsString; btn.BoxNo := FieldByName('BoxNo').AsString; btn.Parent := panel1; btn.Top := y * 50 - 40 ; btn.Left := x * 50 - 40; btn.Height := 50; btn.Width := 50; btn.Font.Size := 14; btn.Caption := FieldByName('BoxNo').AsString; btn.OnClick := ButtonClick; Next; x := x 1; if (x Mod vHorizontalCount) = 1 then begin y := y 1; x := 1; panel1.Height := y * 50 50; end; end; ShowMessage(IntToStr(Panel1.ControlCount)); except MessageDlg('Got Some Error ', mtError, [mbOK], 0); end; end;
======================================== 釋放按鈕的程式 .... 還是會出現 List Out of Bound (30) Error ... 悶 procedure TCabinetListForm.Action2Execute(Sender: TObject); var i : Integer; begin ShowMessage(IntToStr(Panel1.ControlCount)); for I := 0 to Panel1.ControlCount - 1 do TCemeteryBitBtn(Panel1.Controls[i]).Free; ShowMessage(IntToStr(Panel1.ControlCount)); end; |
kending
一般會員 發表:4 回覆:6 積分:2 註冊:2010-08-04 發送簡訊給我 |
我發現一個怪現象,當用如下 的程式去FREE 元件,他會FREE 0,2,4,6,8 的元件
如果有10個元件在 PANEL 內,則 在 FOR Loop 跑到 5 時,就會出現List out of bound (5) . 我現在暫時的解法,是動態產生一個 PANEL . 只要FREE 這個動態的 PANEL 就能把其內的元件 FREE 掉 ? 這樣是否能夠真正 FREE PANEL 內的元件 ? procedure TCabinetListForm.Action2Execute(Sender: TObject); var i : Integer; begin ShowMessage(IntToStr(Panel1.ControlCount)); for I := 0 to Panel1.ControlCount - 1 do TCemeteryBitBtn(Panel1.Controls[i]).Free; ShowMessage(IntToStr(Panel1.ControlCount)); end;
|
老大仔
尊榮會員 發表:78 回覆:837 積分:1088 註冊:2006-07-06 發送簡訊給我 |
[code delphi] for i := Panel1.ControlCount-1 downto 0 do Panel1.Controls[i].Free; [/code] ===================引 用 kending 文 章=================== ? 謝謝版主的回覆,但還是遇到相同的問題, 我是新手所以遇到很多小弟不懂的問題. 如下是我繼承 TBitBtn Class 的元件 Called ?: TCemeteryBitBtn? unit CemeteryUnit; ? interface ? uses Windows, Classes, Graphics, Forms, Controls, StdCtrls, ??Buttons, ExtCtrls; ? type ??TCemeteryBitBtn = class(TBitBtn) ? ??private ?? ?{ Private declarations } ??public ?? ?{ Public declarations } ?? ?TowerID: String; ?? ?FloorID: String; ?? ?DirectionID: String; ?? ?CabinetNo : String; ?? ?BoxNo : String; ??end; ? var ??CemeteryBitBtn: TCemeteryBitBtn; ? implementation ? end. ======================================= 產生按鈕的程式 ? ?// Cabinet Detail ?? ?SQL2 := 'Select * from CabinetDetail ' ?? ? ? ? ? ? ? ?' where TowerID = "' VTowerID '" and FloorID = "' vFloorID '" and ' ?? ? ? ? ? ? ? ? ? ? ? 'DirectionID = "' vDirectionID '" and CabinetNo = ' intToStr(vCabinetNo) ' order by BoxNo asc ?'; ? ?? ?with ADOQueryOfDetail do ?? ?begin ?? ?try ?? ? ? Active := False; ?? ? ? SQL.Clear; ?? ? ? SQL.Add(SQL2); ?? ? ? ExecSQL; ?? ? ? Active := True; ? ?? ? ? ?x := 1 ; ?? ? ? ?y := 1 ; ?? ? ? ?While not Eof Do ?? ? ? ?begin ?? ? ? ? ?btn := TCemeteryBitBtn.Create(self); ?? ? ? ? ?btn.TowerID := FieldByName('TowerID').AsString; ?? ? ? ? ?btn.FloorID := FieldByName('FloorID').AsString; ?? ? ? ? ?btn.DirectionID := FieldByName('DirectionID').AsString; ?? ? ? ? ?btn.CabinetNo := FieldByName('CabinetNo').AsString; ?? ? ? ? ?btn.BoxNo := FieldByName('BoxNo').AsString; ? ?? ? ? ? ?btn.Parent := panel1; ? ?? ? ? ? ?btn.Top := y * 50 - 40 ; ?? ? ? ? ?btn.Left := x * 50 - 40; ?? ? ? ? ?btn.Height := 50; ?? ? ? ? ?btn.Width := 50; ?? ? ? ? ?btn.Font.Size := 14; ?? ? ? ? ?btn.Caption := FieldByName('BoxNo').AsString; ?? ? ? ? ?btn.OnClick := ButtonClick; ? ?? ? ? ? ?Next; ? ?? ? ? ? ?x := x 1; ?? ? ? ? ?if (x Mod vHorizontalCount) = 1 then ?? ? ? ? ?begin ?? ? ? ? ? ?y := y 1; ?? ? ? ? ? ?x := 1; ?? ? ? ? ? ?panel1.Height := y * 50 50; ? ?? ? ? ? ?end; ?? ? ? ?end; ? ?? ? ? ?ShowMessage(IntToStr(Panel1.ControlCount)); ?? ?except ?? ? ? ?MessageDlg('Got Some Error ', mtError, [mbOK], 0); ?? ?end; ?? ?end;
======================================== 釋放按鈕的程式 .... 還是會出現 List Out of Bound (30) Error ... 悶? procedure TCabinetListForm.Action2Execute(Sender: TObject); var ??i : Integer; ?begin ? ?ShowMessage(IntToStr(Panel1.ControlCount)); ?for I := 0 to Panel1.ControlCount - 1 do ?? TCemeteryBitBtn(Panel1.Controls[i]).Free; ? ?ShowMessage(IntToStr(Panel1.ControlCount)); end; ? ? |
老大仔
尊榮會員 發表:78 回覆:837 積分:1088 註冊:2006-07-06 發送簡訊給我 |
您的程式碼在執行的時候
請逐行追蹤 會發現... 當第一次進入迴圈的時候 Count會等於29(假如Button的數量為30) 第二次Count會等於28 以此類推下去 當i在第15個的時候會跟Count一樣 但當i在第16個的時候呢??一定會出錯 所以建議用倒回去數的方法來做~ 另外因為您的寫法是條件在:Panel中所有的元件都是Button 假如不是的話就必須判斷是否為TButton或判斷該元件是否是您要刪的元件 ===================引 用 kending 文 章=================== 我發現一個怪現象,當用如下 的程式去FREE 元件,他會FREE 0,2,4,6,8 ? ?的元件 如果有10個元件在 PANEL 內,則 在 FOR Loop 跑到 5 時,就會出現List out of bound (5) . 我現在暫時的解法,是動態產生一個 PANEL . 只要FREE 這個動態的 PANEL 就能把其內的元件 FREE 掉 ? 這樣是否能夠真正 FREE PANEL 內的元件 ? ? procedure TCabinetListForm.Action2Execute(Sender: TObject); var ??i : Integer; ?begin ? ?ShowMessage(IntToStr(Panel1.ControlCount)); ?for I := 0 to Panel1.ControlCount - 1 do ?? TCemeteryBitBtn(Panel1.Controls[i]).Free; ? ?ShowMessage(IntToStr(Panel1.ControlCount)); end;
編輯記錄
老大仔 重新編輯於 2010-08-10 10:01:02, 註解 無‧
|
kending
一般會員 發表:4 回覆:6 積分:2 註冊:2010-08-04 發送簡訊給我 |
|
老大仔
尊榮會員 發表:78 回覆:837 積分:1088 註冊:2006-07-06 發送簡訊給我 |
|
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |