Delphi 2009 以错误的顺序创建我的组件

标签 delphi components delphi-2009

三个组件协同工作:
* CompA,TComponent 的后代,一个了解许多事物并将事物联系在一起的主脑组件
* CompB 是 TComponent 的后代,从它的 CompA 中挖掘一些数据并对其进行处理。除其他外,还可以向 CompC 提供数据以进行呈现
  - 具有 CompA 类型的已发布属性
* CompC,TComponent 后代,TFrame 后代绘图表面,可以在设计时设置以使用 CompB 作为数据提供者
  - 具有 CompA 类型的已发布属性
  - 具有 CompB 类型的已发布属性

我想我记得读过,尽管我无法说明在哪里,Delphi 的流引擎从 .dfm 读取所有组件并构建依赖关系图。然后使用该图以正确的顺序创建所有组件。对于列出的组件,它应该首先是 CompA(因为它不使用其他组件),然后是 CompB(它使用 CompA 并且必须在之后创建),最后是 CompC,因为它具有其他组件类型的属性。

这不会发生。 CompC 在 CompB 之前创建。如果我使用文本编辑器重新排列 .dfm 文件中的顺序,它就可以工作。属性值不在任何构造函数中使用,仅在 Loaded 过程中使用。但真的必须有一种方法让它工作,无论 dfm 中的组件顺序如何?

我已经连续两天用头撞墙了,我需要有人告诉我我忘记了哪个关键字或者我有什么设计错误。

最佳答案

我怀疑你的错误是你试图访问setter上的其他对象属性来获取同级指针,忘记了在dfm加载阶段--运行时--你无法确定指向其他对象的指针您的组件所依赖的组件仍然有效,因为其他组件可能尚未创建。从 Delphi 1 开始就以这种方式工作。

因此,您通常会将其他组件状态的读取(例如)推迟到您覆盖的 Loaded方法。

When the streaming system loads a form or data module from its form file, it first constructs the form component by calling its constructor, then reads its property values from the form file. After reading all the property values for all the components, the streaming system calls the Loaded methods of each component in the order the components were created. This gives the components a chance to initialize any data that depends on the values of other components or other parts of itself. Note: All references to sibling components are resolved by the time Loaded is called. Loaded is the first place that sibling pointers can be used after being streamed in.

因此,通常在同级指针属性的 setter 方法上执行此类型的检查:

procedure TMyComponent.SetDataSource(Value: TDataSource);
begin
  FDataSource := Value;
  //streaming in stage
  if not (csLoading in ComponentState) then
    ReadDataSourceProperties;
end;

procedure TMyComponent.Loaded;
begin
  ReadDataSourceProperties;
end;

看一下 VCL 源代码,您会发现数百个这样的示例。

关于Delphi 2009 以错误的顺序创建我的组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5166367/

相关文章:

delphi - 如何在Delphi 2009中声明静态变量?

delphi - 如何正确编写Try..Finally..Except语句?

用于包/组件开发的 Delphi 环境设置

delphi - 在实现部分为单元添加 use 子句有哪些优点?

components - 组件中的 Inno Setup 自定义对话框

javascript - 如何动态导入 Vue 3 组件?

delphi - 匿名方法作为函数结果

delphi - 在delphi 2009中创建gif动画文件?

sql - 德尔福7 : Get SQL server system Date and Time format

delphi - Delphi 中带重采样的透明图像控制