MainForm 在运行时创建一些辅助 Frame 对象来显示各种选项面板。
这是其中一个框架类的典型构造函数(它们每个都扩展 TFrame):
constructor Tframe2.Create(AOwner: TComponent);
begin
inherited;
edTime.Text := '12:00pm'; //edTime is a TEdit control. this line is where it throws the exception
//etc.
end;
这段代码在 Delphi 中运行良好(无论它是否是正确的做事方式),但 Lazarus 中的相同代码不断抛出 EInvalidOperation 异常,因为控件(TEdit)尚未分配父“窗口”(rsControlHasNoParentWindow),当我检查代码时,这实际上是有道理的,因为直到调用构造函数之后父级似乎才被分配。
这是 MainForm 中初始化辅助框架的代码:
if Assigned(frame) then FreeAndNil(frame);
case Node.AbsoluteIndex of
optInterval: frame := Tframe2.Create(Self); //here's where the constructor gets called.
//etc
end;
frame := TframeOther.Create(Self);
if Assigned(frame) then
begin
frame.Parent := panOptions; //here's where Tframe2's parent gets set
frame.Align := alClient;
end;
那么,就表单初始化序列而言,任何人都可以解释 Delphi 和 Lazarus 之间是否有任何重要区别?
解决此类初始化顺序问题的最标准方法是什么?与我更熟悉的其他语言相比,可能有不同的策略来解决此类错误。我可以向构造函数添加另一个参数,或者如果有一个方法被称为构造函数后在屏幕上预绘制它,我可以覆盖我可以重新定位该代码,或者只是创建一个辅助方法并在 setParent 被调用后调用它。这里有什么特别的最佳实践吗?
编辑]:看来这可能以某种方式特定于 TEdit。看起来初始化复选框状态的行没有同样的问题。这可能只是拉撒路的一个错误吗?