【问题标题】:Properties of published nested components are not saved, events are not visible in object inspector未保存已发布嵌套组件的属性,事件在对象检查器中不可见
【发布时间】:2020-09-04 12:46:07
【问题描述】:

我创建了一个包含以下内容的组件:

TEditLine = class(TCustomControl)
strict private
  FCaptionLabel: TLabel;
  FUnitLabel: TLabel;
  FEdit: TMyEdit;
end;

然后我开始通过创建相应的 getter/setter 对来传播嵌套组件的必要属性。

我突然想到,将这些嵌套组件本身作为只读属性发布可能会更容易,这样当一些新属性或方法被引入其中一个组件时,不需要更改容器组件接口:

TEditLine = class(TCustomControl)
strict private
  FCaptionLabel: TLabel;
  FUnitLabel: TLabel;
  FEdit: TMyEdit;
published
  property CaptionLabel: TLabel read FCaptionLabel;
  property UnitLabel: TLabel read FUnitLabel;
  property Edit: TMyEdit read FEdit;
end;

当我将组件放在表单上时,我会在 Object Inspector 中看到 CaptionLabel、UnitLabel 和 Edit,但我只能做到这些。

  • 嵌套组件的属性不会保存到 DFM。
  • 它们的事件在对象检查器中不可见。

这样做通常是个好主意吗?我如何解决上面列出的两个问题?

【问题讨论】:

    标签: components delphi-xe5


    【解决方案1】:

    基于TComponent的属性默认被视为对外部组件的引用,除非您在支持它们的对象上调用SetSubComponent(True),例如:

    TEditLine = class(TCustomControl)
    strict private
      FCaptionLabel: TLabel;
      FUnitLabel: TLabel;
      FEdit: TMyEdit;
    public
      constructor Create(AOwner: TComponent); override;
    published
      property CaptionLabel: TLabel read FCaptionLabel;
      property UnitLabel: TLabel read FUnitLabel;
      property Edit: TMyEdit read FEdit;
    end;
    
    ... 
    
    constructor TEditLine.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      ...
      FCaptionLabel := TLabel.Create(Self);
      FCaptionLabel.Parent := Self;
      FCaptionLabel.SetSubComponent(True); // <-- ADD THIS
      ...
      FUnitLabel := TLabel.Create(Self);
      FUnitLabel.Parent := Self;
      FUnitLabel.SetSubComponent(True); // <-- ADD THIS
      ...
      FEdit := TMyEdit.Create(Self);
      FEdit.Parent := Self;
      FEdit.SetSubComponent(True); // <-- ADD THIS
      ...
    end;
    

    【讨论】:

    • 太棒了!有用。现在我将看看是否可以阻止某些嵌套组件的属性出现在 DFM 中。
    • UnlistPublishedProperty()。但是,更好的解决方案是简单地从 TCustomLabelTCustomEdit 派生您自己的类,并且只将您想要的 protected 属性提升到 published (无论如何,您可能需要自定义类才能正确使用 UnlistPublishedProperty() ,因此您不会从标准 TLabel/TEdit 组件中删除属性)。
    • 只有当自定义编辑是TEditLine 的一部分时,我才想隐藏属性。如果它出现在自身上,则所有属性都应该可用。目标不是为自定义编辑维护单独的类定义。如果涉及到创建第二个类,我宁愿将必要的属性传播到 TEditLine 接口而不是 getter 和 setter。
    • @Paul 如果不深入研究编写自定义设计时组件/属性编辑器,您的要求是不可能的。创建另一个基类会更简单,比如TCustomMyEdit,它只公开TEditLine 想要的内容,然后将该类与TEditLine 一起使用。然后从该基类派生 TMyEdit 以将其余属性公开为独立组件。
    猜你喜欢
    • 2014-07-16
    • 2016-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2017-08-17
    相关资源
    最近更新 更多