无法设置Fire Monkey Form属性 [英] Can't set Fire Monkey Form property
问题描述
我正在尝试在Fire Monkey应用程序的程序源文件中初始化表单属性,并且会引发异常.这是代码:
I am trying to initialize form properties in the program source file in a Fire Monkey application and it throws an exception. Here is the code:
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应用程序中做到这一点没有问题.我该如何解决?
I have no problem doing this in a VCL app. How do I fix it?
推荐答案
VCL和FMX之间的行为有所不同-FireMonkey Application.CreateForm
方法.虽然在VCL CreateForm
中实际上创建了表单,并且在调用之后将表单变量完全初始化并准备使用,但在FMX CreateForm
中不会创建表单,并且在调用之后表单变量仍会被未初始化-nil
.因此,使用form变量会抛出AV.
There is difference in behavior between VCL and FMX - FireMonkey Application.CreateForm
method. While in VCL CreateForm
actually creates form and after that call form variable is fully initialized and ready to be used, in FMX CreateForm
does not create form and form variable would still be uninitialized - nil
- after that call. Because of that using form variable throws AV.
CreateForm不会立即创建给定的表单.它只是增加了一个 请求到待处理列表. RealCreateForms创建真实表单.
CreateForm does not create the given form immediately. It just adds a request to the pending list. RealCreateForms creates the real forms.
FMX具有Application.RealCreateForms
方法,该方法在Application.Run
中自动调用.如果在此之前需要使用表单变量,则可以自己调用Application.RealCreateForms
.调用之后,您可以安全地使用通过Application.CreateForm
FMX has Application.RealCreateForms
method that is automatically called in Application.Run
. If you need to use form variables before that, you can call Application.RealCreateForms
yourself. After that call you can safely use form variables you added to the list with Application.CreateForm
请记住,Application.RealCreateForms
仅会进行一次表单创建过程,因此您必须在 向Application.CreateForm
进行了所有调用之后将其称为最终会出现一些单位化的形式.
Keep in mind that Application.RealCreateForms
will go through form creation process only once, so you have to call it after you made all calls to Application.CreateForm
or you will end up with some unitialized forms.
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
时应谨慎行事,并注意潜在的副作用.对于移动平台,最好的选择可能是将您的自定义初始化移到Form OnCreate
事件中.
Note: On Windows and OSX platforms RealCreateForms
is first thing that is called in Application.Run
, so it does not matter whether it is called by you or automatically. However, on Android and iOS platforms additional (initialization) logic happens before RealCreateForms
is called in Application.Run
, if you develop for those platforms, you should proceed with caution when using RealCreateForms
and watch for potential side-effects. Probably the best option for mobile platforms would be to move your custom initialization into Form OnCreate
event.
这篇关于无法设置Fire Monkey Form属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!