2016-01-24 38 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) –