如何中断组件在其构造函数中的加载?
Posted
技术标签:
【中文标题】如何中断组件在其构造函数中的加载?【英文标题】:How to interrupt component from loading in its constructor? 【发布时间】:2012-01-25 18:43:38 【问题描述】:我想在组件无法加载时向我的组件添加条件状态,并通知其用户(开发人员)该组件无法在设计时加载并在运行时以目标用户为目标(如果可能,以某种方式安全)。
如何防止组件在其构造函数中加载,以及如何在设计时和运行时安全地显示来自构造函数的消息(异常)?
constructor TSomeComponent.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if csDesigning in ComponentState then
if SomeIncompatibleCondition then
begin
// how to display message (exception) about the wrong
// condition and interrupt the loading of the component ?
end;
// is it possible to do the same at runtime ?
end;
谢谢
【问题讨论】:
您的测试在构造函数中(不在 Loaded 方法中),因为在开始从 DFM 加载属性之前需要该消息,对吗? 【参考方案1】:一种方法:
Public
Property CreatedOK: boolean read fCreatedOK;
constructor TSomeComponent.Create(AOwner: TComponent);
begin
...
fCreatedOK := ThereIsAnIncompatibleCondition;
end;
然后,程序员通过以下方式创建对象:
MyObject := TSomeComponent.Create(Self);
if (NOT MyObject.CreatedOK) then
... deal with it...
我们更喜欢这个,因为它避免了很多异常代码,这些异常代码可能很麻烦,并且在调试时很麻烦。 (不过那是另一个话题了!)
我们使用的另一种方法是,如果构造函数有很多工作,则将工作转移到用户在构造后必须调用的另一个方法。这还有一个好处,就是让我们可以轻松地将许多值传递给对象。
public
constructor Create...
function InitAfterCreate:boolean;
end;
调用者这样做:
MyObject := TSomeComponent.Create
if (NOT MyObject.InitAfterCreate) then
... deal with it ...
或者,如果您使用 InitAfterCreate 来传递值,您可以将其定义为
function InitAfterCreate( Value1: Integer, etc.):boolean
然后InitAfterCreate可以检查对象的状态并返回结果。
这些方法的一个缺点是程序员必须记住调用 InitAfterCreate 或检查 MyObject.CreatedOk。为了防止他们不这样做,您可以将一些 Asserts 放在对象的其他一些方法的开头,例如:
procedure TForm.FormShow
begin
Assert(fCreatedOK, "Programmer failed to check creation result.")
...
end;
在所有情况下,一个挑战是不终止 Create 使对象处于半创建状态,处于不确定状态,这可能会使您的析构函数难以知道要销毁多少。
【讨论】:
【参考方案2】:引发异常,例如:
constructor TSomeComponent.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if SomeIncompatibleCondition then
raise Exception.Create('Incompatible condition detected!');
end;
【讨论】:
以上是关于如何中断组件在其构造函数中的加载?的主要内容,如果未能解决你的问题,请参考以下文章