模态形式在创建后为零



我正在尝试创建一个表单实例并传递一个参数,该参数必须特定于该实例。

type
  TDataForm = class(TForm)
    { Some components}
    { Some procedures }
    constructor Create(AOwner: TComponent; Data: PData; Page: String); reintroduce;
  private
    { Private declarations }
  public
    { Public declarations }
    ViewedData: PData;
  end;
var CharacterScreen: TDataForm;
implementation

CharacterScreen 是 sucn 实例之一的变量。当我打开比实例时,我是这样做的:

constructor TDataForm.Create(AOwner: TComponent; Data: PData; Page: String);
begin
inherited Create(nil);
ViewedData:=Data;
if Page='Stats'      then CharPageControl.TabIndex:=0;
if Page='Equipment'  then CharPageControl.TabIndex:=1;
if Page='Effects'    then CharPageControl.TabIndex:=2;
if Page='Statistics' then CharPageControl.TabIndex:=3;
ShowModal;
Free;
end;
CharacterScreen:=TDataForm.Create(nil,@Data,'Page 1');

Howewer,如果稍后我调用某个程序而不是表单,我会收到 AV 错误。在分步调试中观察 CharacterScreen 变量时,它被描述为 nil。

所以我的问题是:创建表单实例的正确方法是什么(以便以后我可以创建第二个实例等等(?此外,存储变量 ViewedData 实例的正确方法是否对表单的每个实例都是唯一的?

问题是你从构造函数调用 Free,所以当你关闭窗体时,实例将变得不可访问。

您可以向窗体添加静态方法,并从其他窗体调用该方法。

最佳做法是删除全局表单变量,以便调用代码必须声明局部变量(当您创建同一表单的多个实例时,将变得明显(。在此示例中,我将构造函数设为私有,以便只能在该单元外部调用 execute 方法。

type
  TDataForm = class(TForm)
    { Some components}
    { Some procedures }
  private
    { Private declarations }
    ViewedData: PData;
    constructor Create(AOwner : TComponent);
  public
    { Public declarations }
    class procedure Execute(Data: PData; APage: String);
  end;
implementation
class function TDataForm.Execute(Data: PData; APage: String) :TDataForm;
begin
 Result := TDataForm.Create(nil);
 Result.ViewedData := PData;
 if APage='Характеристики' then Result.CharPageControl.TabIndex:=0 else
 if APage='Экипировка'     then Result.CharPageControl.TabIndex:=1 else
 if APage='Эффекты'        then Result.CharPageControl.TabIndex:=2 else
 if APage='Статистика'     then Result.CharPageControl.TabIndex:=3;
 Result.ShowModal;
end;
constructor TDataForm.Create(AOwner: TComponent);
begin
 inherited Create(nil);
end;

现在你像这样调用你的表单:

var CharacterScreen : TDataForm;
CharacterScreen := TDataForm.Execute(@Data,'Page 1');
try
 // do something with CharacterScreen when it has been closed
finally
 CharacterScreen.Free;   
end;
**

更新 **

现在如果我是你,我会做这样的事情(伪代码,我想你会明白的(:

Unit character;
type
  TCharacterData = class
  public
   // some public fields
  end;
...
Unit EditCharacter;
type 
  TDataForm = class(TForm)
    procedure OnShow(Sender : TObject);
  public
    class procedure Execute(Data : TCharacterData) : Boolean;  
  end;
implementation;
class function TDataForm.Execute(var Character: TCharacter) : Boolean;
var Frm: TDataForm ;
begin
 Result := False; 
 Frm:= TDataForm.Create(nil);
 try
  Frm.Character := Character;
  Frm.ShowModal;
  Result := Frm.ModalResult = mrOK;
 finally
  Frm.Free;
 end;
end;
procedure TDataForm.OnShow(Sender : TObject);
 begin
  if Character = TWizardCharacter then Frm.CharPageControl.TabIndex:=0 else
  if Character = TBarbarianCharacter then Frm.CharPageControl.TabIndex:=1
   ... //etc
 end;

现在调用代码可以如下所示

var Character : TCharacter;
...
Character := TWizardCharacter.Create;
...
// user wants to edit character
procedure EditCharacter;
begin
 if TDataForm.Execute(Character)  then
  begin
   // user has modified character, act accordingly
  end;
end;

相关内容

  • 没有找到相关文章

最新更新