You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据变量中的窗体名创建TForm并传递参数?

动态创建窗体并传递参数的解决方案

下面几种方案可以解决你通过变量指定窗体名称创建实例时的参数传递问题:

方案1:通过公共属性/方法直接传递

这是最直观的方式,给需要接收参数的窗体类定义统一的公共属性或方法,创建窗体后强制类型转换并赋值/调用。

步骤1:给目标窗体定义公共属性

// 示例目标窗体类
type
  TMyForm = class(TForm)
  private
    FUserId: Integer;
    FUserName: string;
  public
    // 定义可写的公共属性
    property UserId: Integer read FUserId write FUserId;
    property UserName: string read FUserName write FUserName;
    // 或者用方法批量传参
    procedure InitParams(AUserId: Integer; AUserName: string);
  end;

// 方法实现示例
procedure TMyForm.InitParams(AUserId: Integer; AUserName: string);
begin
  FUserId := AUserId;
  FUserName := AUserName;
  // 这里可以直接用参数初始化控件,比如给Label赋值
  lblUserName.Caption := AUserName;
end;

步骤2:修改创建窗体的代码

procedure TFrmTeste.CriaForm(FormName: String);
var
  FrmClass: TFormClass;
  Frm: TForm;
begin
  FrmClass := TFormClass(FindClass(FormName));
  Frm := FrmClass.Create(Application);
  try
    // 判断窗体类型,然后传递参数
    if Frm is TMyForm then
    begin
      // 方式1:直接给属性赋值
      TMyForm(Frm).UserId := 1001;
      TMyForm(Frm).UserName := '张三';
      // 方式2:调用批量传参方法
      // TMyForm(Frm).InitParams(1001, '张三');
    end
    // 可以添加其他窗体类型的判断逻辑
    else if Frm is TOtherForm then
    begin
      TOtherForm(Frm).SomeParam := '其他参数';
    end;

    Frm.ShowModal;
  finally
    Frm.Free;
  end;
end;

方案2:用接口统一规范参数传递

定义一个带参数设置方法的接口,让所有需要传参的窗体实现该接口,创建后通过接口传递参数,避免大量类型判断。

步骤1:定义接口

// 生成GUID可以用Delphi的Ctrl+Shift+G快捷键
type
  IFormParamSetter = interface
    ['{E8B5F6D3-4F1A-4C7D-9E2B-1A3F4D7C8E90}']
    procedure SetUserParams(AUserId: Integer; AUserName: string);
  end;

步骤2:目标窗体实现接口

type
  TMyForm = class(TForm, IFormParamSetter)
  private
    FUserId: Integer;
    FUserName: string;
  public
    procedure SetUserParams(AUserId: Integer; AUserName: string);
  end;

procedure TMyForm.SetUserParams(AUserId: Integer; AUserName: string);
begin
  FUserId := AUserId;
  FUserName := AUserName;
  lblUserName.Caption := '当前用户:' + AUserName;
end;

步骤3:修改创建代码

procedure TFrmTeste.CriaForm(FormName: String);
var
  FrmClass: TFormClass;
  Frm: TForm;
  ParamSetter: IFormParamSetter;
begin
  FrmClass := TFormClass(FindClass(FormName));
  Frm := FrmClass.Create(Application);
  try
    // 尝试获取接口,支持就传参
    if Supports(Frm, IFormParamSetter, ParamSetter) then
    begin
      ParamSetter.SetUserParams(1001, '张三');
    end;

    Frm.ShowModal;
  finally
    Frm.Free;
  end;
end;

方案3:用RTTI动态设置属性

如果不想修改窗体类的结构,可以借助RTTI(运行时类型信息)直接设置窗体的公共属性,适合参数较多且分散的场景。

代码示例(需引用RTTI单元)

uses
  RTTI;

procedure TFrmTeste.CriaForm(FormName: String);
var
  FrmClass: TFormClass;
  Frm: TForm;
  RttiCtx: TRttiContext;
  RttiType: TRttiType;
  TargetProp: TRttiProperty;
begin
  FrmClass := TFormClass(FindClass(FormName));
  Frm := FrmClass.Create(Application);
  try
    RttiCtx := TRttiContext.Create;
    try
      RttiType := RttiCtx.GetType(Frm.ClassType);
      
      // 设置UserId属性
      TargetProp := RttiType.GetProperty('UserId');
      if Assigned(TargetProp) and TargetProp.IsWritable then
        TargetProp.SetValue(Frm, 1001);
      
      // 设置UserName属性
      TargetProp := RttiType.GetProperty('UserName');
      if Assigned(TargetProp) and TargetProp.IsWritable then
        TargetProp.SetValue(Frm, '张三');
    finally
      RttiCtx.Free;
    end;

    Frm.ShowModal;
  finally
    Frm.Free;
  end;
end;

方案4:自定义构造函数(需统一窗体基类)

如果必须通过构造函数传参,可以定义一个带参数的构造函数,让所有目标窗体继承并实现该构造函数。

步骤1:定义带参数的窗体类引用

type
  TFormWithParamsClass = class of TForm
  public
    constructor CreateWithParams(AOwner: TComponent; AUserId: Integer; AUserName: string); reintroduce; virtual;
  end;

// 基类构造函数实现
constructor TFormWithParamsClass.CreateWithParams(AOwner: TComponent; AUserId: Integer; AUserName: string);
begin
  inherited Create(AOwner);
  // 基类逻辑留空,子类重写实现参数处理
end;

步骤2:目标窗体实现自定义构造函数

type
  TMyForm = class(TForm, TFormWithParamsClass)
  private
    FUserId: Integer;
    FUserName: string;
  public
    constructor CreateWithParams(AOwner: TComponent; AUserId: Integer; AUserName: string); override;
  end;

constructor TMyForm.CreateWithParams(AOwner: TComponent; AUserId: Integer; AUserName: string);
begin
  inherited CreateWithParams(AOwner, AUserId, AUserName);
  FUserId := AUserId;
  FUserName := AUserName;
  lblUserName.Caption := '用户:' + AUserName;
end;

步骤3:修改创建代码

procedure TFrmTeste.CriaForm(FormName: String);
var
  FrmClass: TFormWithParamsClass;
  Frm: TForm;
begin
  FrmClass := TFormWithParamsClass(FindClass(FormName));
  // 直接调用自定义构造函数传参
  Frm := FrmClass.CreateWithParams(Application, 1001, '张三');
  try
    Frm.ShowModal;
  finally
    Frm.Free;
  end;
end;

内容的提问来源于stack exchange,提问作者Renato Benedetti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:32:37