全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3176
推到 Plurk!
推到 Facebook!

如何釋放在 Panel 裏所建立的動態按鈕元件

答題得分者是:老大仔
kending
一般會員


發表:4
回覆:6
積分:2
註冊:2010-08-04

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-08-10 00:06:18 IP:61.227.xxx.xxx 訂閱
 我在 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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-08-10 07:59:22 IP:123.50.xxx.xxx 未訂閱
procedure TCabinetListForm.Action2Execute(Sender: TObject);
var
i : Integer;
begin
for I := 0 to Panel1.ControlCount - 1 do
TBitBtn(Panel1.Controls[i]).Free;
end;
------
聰明的人,喜歡猜心;雖然每次都猜對了,卻失去了自己的心
傻氣的人,喜歡給心;雖然每次都被笑了,卻得到了別人的心
kending
一般會員


發表:4
回覆:6
積分:2
註冊:2010-08-04

發送簡訊給我
#3 引用回覆 回覆 發表時間:2010-08-10 08:50:14 IP:61.227.xxx.xxx 訂閱
 
謝謝版主的回覆,但還是遇到相同的問題,
我是新手所以遇到很多小弟不懂的問題.
如下是我繼承 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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2010-08-10 09:50:09 IP:61.227.xxx.xxx 訂閱
我發現一個怪現象,當用如下 的程式去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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2010-08-10 09:53:43 IP:59.120.xxx.xxx 未訂閱


[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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2010-08-10 09:59:48 IP:59.120.xxx.xxx 未訂閱
您的程式碼在執行的時候
請逐行追蹤
會發現...
當第一次進入迴圈的時候
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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2010-08-10 10:02:39 IP:61.227.xxx.xxx 訂閱
 真是強。。。。
真是神來之筆。。。。

可以告訴我原理嗎 ? for i := Panel1.Controlcount downto 0 do


DOWNTO

不能由小至大... 要由大至小.....

謝謝啦!


老大仔
尊榮會員


發表:78
回覆:837
積分:1088
註冊:2006-07-06

發送簡訊給我
#8 引用回覆 回覆 發表時間:2010-08-10 10:09:39 IP:59.120.xxx.xxx 未訂閱
強@@?
比起本站裡的前輩們...
我只是個也剛學Delphi沒多久的小嘍囉= =

原理???
我已經有回覆過了呀...@@



===================引 用 kending 文 章===================
?真是強。。。。
真是神來之筆。。。。

可以告訴我原理嗎 ? ?for ?i := Panel1.Controlcount downto 0 do ??


DOWNTO?

不能由小至大... 要由大至小.....?

謝謝啦!?


編輯記錄
老大仔 重新編輯於 2010-08-10 10:11:02, 註解 無‧
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#9 引用回覆 回覆 發表時間:2010-08-11 12:16:39 IP:112.104.xxx.xxx 未訂閱
TBitBtn.Create(AOwner);

這些 TBitBtn 的釋放動作, 自有 AOwner 來做, 何需代勞?
除非 AOwner = nil
編輯記錄
jow 重新編輯於 2010-08-11 12:17:56, 註解 無‧
系統時間:2024-03-29 22:33:09
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!