在使用Create / AfterConstruction代码时,我有两个独立的要求来检测是否从流中创建对象。
在第一种情况下,我有一个现有对象,该对象将被重新设计,因此它被实现为一个组件,以允许消耗用户将组件拖放到表单或数据模块上。该组件的属性之一是Uuid,它需要唯一地分配给每个对象实例,并且需要在程序的不同运行期间对该对象实例保持唯一。在内部,Uuid保存在我们自己的类中,但是我们在IDE中向用户提供了UuidString属性。我需要知道是分配一个Uuid并在首次创建时注册该组件,还是等到Loaded例程(如果不从流中读取该例程则永远不会调用)。
在第二种情况下,我有一组向应用程序提供“ OnReady”事件的组件。一旦对象完全初始化(可以是异步的),便会调用该事件。如果正在流传输对象,那么我可以重写Loaded方法以进行其他配置,但是如果不流传输,则将永远不会调用Loaded,我应该在AfterConstruction中开始其他工作。
看我可以使用的文档:
if( not (csLoading in Self.ComponentState) ) then
...
或者,要专门在设计器中捕获新创建的对象:
if( (csDesigning in Self.ComponentState) And
not (csLoading in Self.ComponentState) ) then
...
但是,尽管看了一下代码(从背景上来说我并不是真正的Delphi程序员),但我发现csLoading仅在执行了Create / AfterConstruction后设置。
在Create / AfterConstruction执行期间,是否可以告诉我是否要调用Loaded?
我已经意识到通过流传输创建的所有组件将具有Owner<>nil
,但是期望在运行时创建的组件通常也具有Owner<>nil
。
此刻,我唯一的想法是查看所有者是否正在加载类似的内容:
if( (Self.Owner<>nil) And (not (csLoading in Self.Owner.ComponentState)) ) then
...
这是正确的方法吗?还是有更好的“德尔福方式”来做到这一点?
答案 0 :(得分:0)
假设您的财产以UUIDString
为后盾,命名为FUUIDString
。然后这种方法应该起作用:
type
TMyComponent = class(TComponent)
private
FUUIDString: string;
function GetUUIDString: string;
protected
procedure Loaded; override;
public
property UUIDString: string read GetUUIDString write FUUIDString;
end;
function TMyComponent.GetUUIDString: string;
begin
if FUUIDString = '' then
FUUIDString := CreateNewUUIDString;
Result := FUUIDString;
end;
procedure TMyComponent.Loaded;
begin
inherited;
RegisterUUIDString(UUIDString);
end;
如果在流读取过程中加载了UUIDString
,它将包含存储的值。否则,Loaded内部的注册调用将生成一个新的调用。