its*_*ols 1 delphi lazarus dynamic-forms
我在设计时创建了5个表单.我需要动态创建每个表单的实例并放在一个选项卡上.
我的问题:如果表单名称在字符串数组中,我调用我的过程如下:
ShowForm(FormName[3]);// To show the 3rd form on a tab page.
Run Code Online (Sandbox Code Playgroud)
如何为每个表单定义和创建新实例?
这就是我现在所拥有的:
procedure TForm1.ShowFormOnTab(pProcName:String);
var
NewForm: TfrmSetupItemCategories;//***HERE IS MY PROBLEM***
NewTab: TTabSheet;
FormName: String;
begin
NewTab := TTabSheet.Create(PageControl1);
NewTab.PageControl:= PageControl1;
NewTab.Caption:='hi';
PageControl1.ActivePage := NewTab;
if pProcName='ProcfrmSetupItemCategories' Then
begin
NewForm:=TfrmSetupItemCategories.Create(NewTab);
NewTab.Caption := NewForm.Caption;
end;
if pProcName='ProcfrmZones' Then
begin
NewForm:=TfrmZones.Create(NewTab);
NewTab.Caption := NewForm.Caption;
end;
.
.
.
end;
Run Code Online (Sandbox Code Playgroud)
" 我的问题就是这里"这一行是我需要帮助的地方.我不能以这种方式将NewForm重用为具有第二种形式的变量......
注意:我的问题不是标签.而是使用相同的变量名创建表单的新实例.
将NewForm变量声明为TForm:
var
NewForm: TForm;
begin
NewForm := TMyForm.Create(Tab1); //compiles OK
NewForm := TMyOtherForm.Create(Tab2); //also compiles OK
end;
Run Code Online (Sandbox Code Playgroud)
我假设TMyForm和TMyOtherForm都是TForm的衍生物.
您还可以使用类引用变量减少重复代码,如下所示:
procedure TForm1.ShowFormOnTab(pProcName:String);
var
NewForm: TForm;
ClassToUse: TFormClass;
NewTab: TTabSheet;
FormName: String;
begin
NewTab := TTabSheet.Create(PageControl1);
NewTab.PageControl:= PageControl1;
NewTab.Caption:='hi';
PageControl1.ActivePage := NewTab;
if pProcName='ProcfrmSetupItemCategories' then
ClassToUse := TfrmSetupItemCategories
else if pProcName='ProcfrmZones' then
ClassToUse := TfrmZones
else
ClassToUse := nil;
if Assigned(ClassToUse) then
begin
NewForm := ClassTouse.Create(NewTab);
NewTab.Caption := NewForm.Caption;
//if you access custom properties or methods, this is the way:
if NewForm is TfrmZones then
TfrmZones(NewForm).ZoneInfo := 'MyInfo';
end;
end;
Run Code Online (Sandbox Code Playgroud)
正如Rufo爵士在评论中指出的那样,你甚至可以进一步注册你的课程(我不确定这是否可以在Lazarus中完成,这项练习取决于你).
首先,在调用ShowFormOnTab方法之前,从类名注册要实例化的表单类,例如:
procedure TMainForm.FormCreate(Sender: TObject);
begin
RegisterClass(TfrmSetupItemCategories);
RegisterClass(TfrmZones);
//and other classes
end;
Run Code Online (Sandbox Code Playgroud)
然后,您可以更改代码以从类名字符串中获取类引用:
procedure TForm1.ShowFormOnTab(pProcName:String);
var
NewForm: TForm;
ClassToUse: TFormClass;
ClassNameToUse: string;
NewTab: TTabSheet;
FormName: String;
begin
NewTab := TTabSheet.Create(PageControl1);
NewTab.PageControl:= PageControl1;
NewTab.Caption:='hi';
PageControl1.ActivePage := NewTab;
//get rid of 'Proc' and add the T
//or even better, pass directly the class name
ClassNameToUse := 'T' + Copy(pProcName, 5, MaxInt);
ClassToUse := TFormClass(FindClass(ClassNameToUse));
if Assigned(ClassToUse) then
begin
NewForm := ClassTouse.Create(NewTab);
NewTab.Caption := NewForm.Caption;
//if you access custom properties or methods, this is the way:
if NewForm is TfrmZones then
TfrmZones(NewForm).ZoneInfo := 'MyInfo';
end;
end;
Run Code Online (Sandbox Code Playgroud)
这样,代码对于任何数量的类都保持不变.
有关这方面的更多信息,请参阅delphi.about.com中的字符串创建Delphi表单.