2016-01-24 63 views
3

我想在火猴应用程序中的程序源文件中初始化窗体属性,并且它会引发异常。这里是代码:无法设置火猴表单属性

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. 

我没有问题在VCL应用程序中这样做。我如何解决它?

回答

7

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; 
    .... 

注意:在Windows和OSX平台RealCreateForms是称为Application.Run第一件事情,所以它并不重要,无论是由您或自动调用。但是,在Android和iOS平台上,额外的(初始化)逻辑会在Application.Run中调用RealCreateForms之前发生,如果您为这些平台开发,则在使用RealCreateForms时应谨慎行事,并注意潜在的副作用。移动平台的最佳选择可能是将您的自定义初始化移动到表单OnCreate事件中。

+0

谢谢!有用! – joeb545

+1

默认情况下''RealCreateForms()'在'Application.Run()'中被调用。 –

+1

如果这是正确的答案,请接受它。 [接受答案的工作方式](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) –