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 有关的特定问题。看起来初始化复选框状态的行没有出现同样的问题。这只是 Lazarus 中的一个 bug 吗?