无法设置Fire Monkey Form属性

Ter*_*son 3 delphi firemonkey

我试图在Fire Monkey应用程序中的程序源文件中初始化表单属性,它会抛出异常.这是代码:

uses
    System.StartUpCopy,
    FMX.Forms,
    uMainForm in 'Units\uMainForm.pas' {MainForm},
    UDataModule in 'Units\UDataModule.pas' {DataMod: TDataModule},
    DataHelperClasses in 'Units\DataHelperClasses.pas',
    EXDIntf in 'Units\EXDIntf.pas',
    Exd in 'Units\Exd.pas';

    {$R *.res}
    var
      ViewModel: TEXDViewModel;
    begin
      Application.Initialize;
      Application.CreateForm(TDataMod, DataMod);
      Application.CreateForm(TMainForm, MainForm);
      ViewModel := TEXDViewModel.Create;
      MainForm.Data := DataMod;
      MainForm.ViewModel := ViewModel;  //This throws an access violation exception
      ViewModel.Data := DataMod;
     Application.Run;
end.
Run Code Online (Sandbox Code Playgroud)

在VCL应用程序中执行此操作我没有问题.我如何解决它?

Dal*_*kar 8

VCL和FMX之间的行为有所不同 - FireMonkey Application.CreateForm方法.虽然在VCL中CreateForm实际上创建了表单,然后调用表单变量完全初始化并准备好使用,但在FMX CreateForm中不创建表单和表单变量仍然是未初始化的nil- 在该调用之后.因为使用表单变量抛出AV.

FMX.TApplication.CreateForm

CreateForm不会立即创建给定的表单.它只是向待处理列表添加了一个请求.RealCreateForms创建真实的表单.

FMX具有Application.RealCreateForms自动调用的方法Application.Run.如果您需要在此之前使用表单变量,则可以自行调用Application.RealCreateForms.在该调用之后,您可以安全地使用添加到列表中的表单变量Application.CreateForm

请记住,Application.RealCreateForms只会进行一次表单创建过程,因此您必须完成所有调用调用它,Application.CreateForm否则最终会得到一些单元化表单.

begin
  Application.Initialize;
  Application.CreateForm(TDataMod, DataMod);
  Application.CreateForm(TMainForm, MainForm);

  // this forces creation of FireMonkey forms
  Application.RealCreateForms;
  ....
Run Code Online (Sandbox Code Playgroud)

注意:在Windows和OSX平台RealCreateForms上首先调用Application.Run它,因此无论是由您调用还是自动调用它都无关紧要.但是,在Android和iOS平台上,在RealCreateForms调用之前会发生额外的(初始化)逻辑Application.Run,如果您为这些平台开发,则在使用RealCreateForms和注意潜在的副作用时应谨慎行事.移动平台的最佳选择可能是将自定义初始化移动到Form OnCreate事件中.