如何动态建立控件组?(200分)

M

margie

Unregistered / Unconfirmed
GUEST, unregistred user!
如何动态建立控件组?控件数目在设计阶段未知。
 
Z

ZZZ

Unregistered / Unconfirmed
GUEST, unregistred user!
试试下面的代码:
var
BtnList : TList;

Procedure TForm1.DynCreateBtn;
var
Btn : TButton;
begin
Btn := TButton.Create(Self);
...
BtnList.Add(Btn);
end;

 
C

cpp

Unregistered / Unconfirmed
GUEST, unregistred user!

开一个工程,FORM上放一个BUTTON,CLICK事件如下:

procedure TForm1.Button1Click(Sender: TObject);
var
button:array[1..10] of Tbutton
//定义
i:integer;
begin
for i:=1 to 3 do
begin
button:=TButton.Create(self)
//创建
button.Parent:=Form1
//必须加入!!!
button.top:=80;
button.left:=(i-1)*100+50;
button.caption:='Button['+inttostr(i)+']';
// 不用的时候要释放,见下面。
{* for i:=1 to 3 do
begin
if Assigned(button) then button.Free;
end;
*}
end;
end;


OK了吧!!!!!!
 

柳五公子

Unregistered / Unconfirmed
GUEST, unregistred user!
按你的要求,ZZZ的答案应是最佳。我在此补充几点。
1. 在TForm1.DynCreateBtn中必须加入:
Btn.parent :=self
//否则不会显示出来
Btn.click :=btnClick
//响应此Button的Click事件
{ 其中 btnClick必须在TForm1的public中定义
procedure btnClick(Sender :TObject);
}

2. 若要为不同的Button写不同的事件
在TForm1.DynCreateBtn中加入:
Btn.tag :=BtnList.Count
//加入标识
在btnClick中加入:
case TButton(Sender).sender of
1: ...
2: ...

#
 
A

aimingoo

Unregistered / Unconfirmed
GUEST, unregistred user!
给你一个较全面的解决方案:
=========================
{ 1.如下函数来自我的函数库,是一个通用且稳定的动态创建函数 }

//动态创建一个可视组件.
Function GetAComp( OwnerName : Tcomponent;
CompType : TControlClass;
CompName : String;
X,Y,W,H:Integer) : TControl;
begin
if (OwnerName.FindComponent(Compname) <> nil) and
not(OwnerName.FindComponent(Compname) is TControl)
then begin Result := Nil
exit
end;
Result := OwnerName.FindComponent(CompName) as TControl;
if Result = Nil
then
begin
Result := CompType.Create(OwnerName);
with Result do
begin
if OwnerName is TwinControl then
begin
SetBounds(X,Y,W,H);
Parent := TwinControl(OwnerName);
{ 如果是可视构件,则显示之 }
if OwnerName is TForm
then TForm(OwnerName).ActiveControl := TWinControl(Result);
{ 设置窗口焦点 }
end;
end;
Result.Name := CompName;
end
else { Result <> Nil }
if not(Result is CompType)
then begin Result := Nil
Exit
end;
Result.Visible := True;
end;

{ 2.对于未知数量的控件组,可采用建立动态数组的方法,但在Delphi3中
只支持在函数参量中使用动态数组,听说D4已可构造动态数组,但我
没有用过。下面的方法利用了Tlist和类类型来实现了你的需求}

//利用TList
//=========
var ControlList : Tlist;
CreateNum : integer;
const CreateClass : TControlClass = TButton;
// 你可以任意修改TControlClass = TEdit或TPanel等。效果一样。

procedure TForm1.Button1Click(Sender: TObject);
var i:integer
p : Pointer;
begin
ControlList := TList.Create;
ControlList.Clear;
CreateNum := 10;
for i:=1 to CreateNum do
begin
p := Pointer(GetAComp(self,CreateClass,'TestB' + IntToStr(i),0,i * 20 + 1,60,20))
//创建
ControlList.add(p);
end;
end;

Procedure TForm1.Button2Click(Sender: TObject);
var i : integer;
begin
With ControlList do
for i := Count - 1 DownTo 0 do
begin TControl(items).Destroy
Delete(i)
end;
//释放
CreateNum := 0;
end;
 
A

aimingoo

Unregistered / Unconfirmed
GUEST, unregistred user!
Sorry.Sorry.
忘了忘了。应该在Button2Click()处理的CreateNum := 0;一句后加入
ControlList.Free;一句,以释放开始创建的TList对象。
^-^
 
H

huizhang

Unregistered / Unconfirmed
GUEST, unregistred user!
看来这个问题讨论的很详细了,为了部丢分也加两句

该议题很有使用价值, 如果能与数据库相连, 可以解决很多问题, 例如一个电路控制
板中的指示灯的位置、状态等信息存放在一个数据表中,动态地生成一些TShape来画出这些指示灯、并根据数据库信息实时地改变灯的颜色
 
顶部