動態創建控件及刪除的BUG,裡面有代碼

才子鸣 2008-07-15 03:27:51
如果我在一個Form上動態創建50個控件,50個控件裡有CheckBox,Combobox,Edit等。
我用下面的代碼
for i:=0 to sb1.ControlCount-1 do
begin
if (sb1.Controls[i] is TCustomEdit)then
(sb1.Controls[i] as TEdit).Free;
end;
但實際上還是不能把所有的TEdit找到來Free掉
不知道是BUG還是其他什麼原因!
...全文
164 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
才子鸣 2008-07-15
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 hongqi162 的回复:]
Delphi(Pascal) code


for i:=sb1.ControlCount-1 downto 0 do
begin
if (sb1.Controls[i] is TEdit) then
TEdit(sb1.Controls[i]).Free; //注意这里你遍历的是sb1
end;
[/Quote]

呵呵真不好意思。正如您所說的。
TEdit(sb1.Controls[i]).Free; //這裡少掉了sb1

現在功能OK
感覺 感謝失踪的月亮賴心的幫忙!!!
才子鸣 2008-07-15
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 hongqi162 的回复:]
Delphi(Pascal) code
你把我这个单元测试一下看看你那里不对

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
s:Integer;

[/Quote]

按您的方法。
點一下Button之後Form上出現10個Edit.
再繼續點Button,Form上的Edit是點一下消失一個,點10下後,10個Edit全消失。
就再也不出來了!
hongqi162 2008-07-15
  • 打赏
  • 举报
回复
  


for i:=sb1.ControlCount-1 downto 0 do
begin
if (sb1.Controls[i] is TEdit) then
TEdit(sb1.Controls[i]).Free; //注意这里你遍历的是sb1
end;
hongqi162 2008-07-15
  • 打赏
  • 举报
回复

你把我这个单元测试一下看看你那里不对

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
s:Integer;
procedure CreateNewEdit(count:Integer);
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
begin
for i:=self.ControlCount-1 downto 0 do
begin
if (self.Controls[i] is TEdit) then
TEdit(Controls[i]).Free
end;
if s>0 then
CreateNewEdit(s);
end;

procedure TForm1.CreateNewEdit(count: Integer);
var
MyEdit:TEdit;
i:Integer;
begin
for i:=0 to count-1 do
begin
MyEdit:= TEdit.Create(Owner);
MyEdit.Top:=i*50;
MyEdit.Parent:=self;
MyEdit.Width:=100;
MyEdit.Height:=30;
MyEdit.Visible:=True;
end;
inc(s,-1);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
s:=10;
end;

end.
才子鸣 2008-07-15
  • 打赏
  • 举报
回复
非常感謝:失踪的月亮

我的代碼是這樣的


procedure Tfmfaliao.RefreshForm;
var
i:Integer;
begin
// for i:=sb1.ControlCount-1 Downto 0 do
// begin
// if (sb1.Controls[i] is TEdit) then
// TEdit(Controls[i]).Free;
// end;

for i:=sb1.ControlCount-1 downto 0 do
begin
if (sb1.Controls[i] is TEdit) then
TEdit(Controls[i]).Free
end;
end;

function Tfmfaliao.CreateNewTurnInRecord(const ATop: Integer): TBaseTurnInData;
begin
with Result do
begin
Result := TBaseTurnInData.Create(Self);
CheckBox := CreateNewCheckBox(Result, sb1, ATop-19, 8, 17);
PartNOEdit := CreateNewEdit(Result,sb1,ATop-19,28,121);
QtyEdit := CreateNewEdit(Result,sb1,ATop-19,159,57);
Qty2Edit := CreateNewEdit(Result,sb1,ATop-19,226,57);
Qty3Edit := CreateNewEdit(Result,sb1,ATop-19,294,57);
MOEdit := CreateNewEdit(Result,sb1,ATop-19,361,121);
Qty4Edit := CreateNewEdit(Result,sb1,ATop-19,496,57);
CheckBox.OnClick := chkTurnInClick;
Qty4Edit.OnKeyPress := IntegerEditKeyPress;
Qty4Edit.OnChange := chkQty4OnChange;
end;
end;


procedure Tfmfaliao.tlRefreshClick(Sender: TObject);
var
I:Integer;
ATurnIn:TBaseTurnInData;
begin
RefreshForm; //這就是要刷新Form的方法了。
I := 1;
TWip_Runcard.GetWipTurnByWO3(quGet,quGet1,lsPNQuery.Items);

while not quGet.Eof do
begin
ATurnIn := CreateNewTurnInRecord(i*27) ;//這裡是新建控件
with ATurnIn,quGet do //quGet查到多少條記錄,就要創建多少行Edit,每行是5個Edit.有時候查詢出來1條記錄,但有時候查詢出來2條,但有時候可能一條記錄都沒有,所以,當沒有記錄的時候,之前顯示在Form上的Edit要全部Free掉,
begin
PartNOEdit.Text := FieldByName('Part_NO').AsString;
QtyEdit.Text := FieldByName('TOTAL').AsString;
Qty2Edit.Text := FieldByName('Yifa').AsString;
Qty3Edit.Text := FieldByName('Kefa').AsString;
CheckBox.Enabled := StrToInt(Qty3Edit.Text) <> 0;
TurnInList.Add(ATurnIn);
Inc(i);
quGet.Next;
end;
end;
end;

在刷 新Form後。也就是把之前創建的Edit Free掉後,
我會再新建Edit,然後向裡面寫一些資料。

hongqi162 2008-07-15
  • 打赏
  • 举报
回复
var
i:Integer;
MyEdit:TEdit;
begin
for i:=self.ComponentCount-1 downto 0 do
begin
if (self.Components[i] is TEdit) then
TEdit(Components[i]).Free
end;
for i:=0 to 5 do
begin
MyEdit:= TEdit.Create(Owner);
MyEdit.Top:=i*50;
MyEdit.Parent:=self;
MyEdit.Width:=100;
MyEdit.Height:=30;
MyEdit.Visible:=True;
end;
end;
才子鸣 2008-07-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 yuqianyi1974 的回复:]
Delphi(Pascal) code
procedure TForm1.Button2Click(Sender: TObject);
var
i:integer;
begin
for i:=self.ControlCount-1 downto 0 do
begin
if (self.Controls[i] is TEdit) then
TEdit(Controls[i]).Free
end;
end;
[/Quote]

第一次點新建,6個Edit正常顯示。
第二次點新建,就報錯了List Out of Bounds(6)

So還得麻煩各位大哥們繼續指教!

才子鸣 2008-07-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hongqi162 的回复:]
Delphi(Pascal) code修改成这样

for i:=self.ComponentCount-1 downto 0 do
begin
if (self.Components[i] is TEdit) then
TEdit(Components[i]).Free
end;
[/Quote]



這種方法,我第一次點新建按鈕時是先建6個Edit,正常,
第二次點新建 按鈕是是建12個Edit,正常。
第三次又隻建6個Edit,正常,但是第二次建的12個Edit有6個被這次建的6個覆蓋。
還有6個任然在Form上,沒有消失!

所以我現在的需求就是把之前建的全刪除,再重新建6個Edit在Form上!
tpcnyou 2008-07-15
  • 打赏
  • 举报
回复
当从一个列表中进行大量删除时 循环需要用 downto,这样就不会因为删除某个列项时会报list指针不对。
yuqianyi1974 2008-07-15
  • 打赏
  • 举报
回复

procedure TForm1.Button2Click(Sender: TObject);
var
i:integer;
begin
for i:=self.ControlCount-1 downto 0 do
begin
if (self.Controls[i] is TEdit) then
TEdit(Controls[i]).Free
end;
end;
hongqi162 2008-07-15
  • 打赏
  • 举报
回复
修改成这样  

for i:=self.ComponentCount-1 downto 0 do
begin
if (self.Components[i] is TEdit) then
TEdit(Components[i]).Free
end;
hongqi162 2008-07-15
  • 打赏
  • 举报
回复
for i:=0 to sb1.ControlCount-1 do
=》
for i:=0 to sb1.ComponentCount-1 do

5,928

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧