无法声明字符串属性默认值

时间:2014-02-23 01:17:40

标签: delphi properties components default-value

我正在编写一个组件,其中包含许多属性,这些属性将出现在Delphi IDE Object Inspector(已发布的属性)中......

type
  TMyComponent = class(TComponent)
  private
    FMyProperty: String;
  published
    property MyProperty: String read FMyProperty write SetMyProperty default 'Something';
  end;

但是,它不允许我将默认值应用于字符串属性...

[DCC Error] MyUnit.pas(278): E2146 Default values must be of ordinal, pointer or small set type

所有其他属性默认值都可以正常工作(Integer,Enum等)。

我的目标是A)如果它们是默认值,则不将字符串属性保存到DFM,B)如果它不是默认值,则将对象检查器中的值显示为粗体,并且如果是的话。此组件有超过130个属性,其中大约50个是字符串属性,有些属性具有相当大的默认值。

为什么我不允许使用默认值声明字符串属性?这是Delphi的一个缺点,还是有技术上的原因导致字符串不能被默认?

修改

如果您真的想知道我在做什么,我将封装Inno Setup并将功能包装到具有广泛属性/集合编辑器的组件中。本主题仅涉及Setup部分,实际上包含100多个属性。预计这些属性中只有大约20个实际用于简单实现,因此我不希望所有其余的字符串属性膨胀DFM的大小(如果它们设置为默认值)。根据组件的设置方式,它将生成一个Inno Setup脚本文件。

2 个答案:

答案 0 :(得分:7)

只有数字属性可以在属性声明中指定default值。但是,您可以使用stored说明符,例如:

type
  TMyComponent = class(TComponent)
  private
    FProp: String;
    function MyPropIsStored: Boolean;
    procedure SetProp(const Value: String);
  public
    constructor Create(AOwner: TComponent); override;
  published
    property MyProp: String read FProp write SetProp stored MyPropIsStored;
end;

constructor Create(AOwner: TComponent); override;
begin
  Inherited;
  FProp := 'my default value';
end;

function TMyComponent.MyPropIsStored: Boolean
begin
  Result := FProp <> 'my default value';
end;

答案 1 :(得分:2)

目前尚不清楚你要做什么。将default分配给属性有两个用途:

  • 要确定属性值是否流式传输到DFM(通常用于序数或布尔属性,例如Visible - 因为默认值为True,所以没有有理由将其写入DFM,除非它是False。(见下面的注释)

  • 对于数组属性,要指示数组是类的默认属性(例如Delphi的TList.Items,其中Items默认允许您使用List[x]而不是代码中的List.Items[x]

如果您的目的是为字符串提供默认值,以便它在Object Inspector中显示,只需在组件构造函数中设置值即可。如果用户分配了不同的值,则在流式传输DFM内容时,将覆盖构造函数中设置的值。

至于为什么不允许使用字符串默认值,documentation中明确说明了这一点(请参阅“存储说明符”(强调我的):

  

默认和nodefault指令仅对序数类型和集合类型支持,前提是集合的基本类型的上限和下限具有0到31之间的序数值;如果声明这样的属性没有默认属性或nodefault,则将其视为指定了nodefault。 对于实数,指针和字符串,隐式默认值分别为0,nil和''(空字符串)。

注意:默认值与Remy的答案描述的存储说明符一起使用。来自上面链接和引用的相同文档(同一部分):

  

保存组件的状态时,将检查组件已发布属性的存储说明符。 如果属性的当前值与其默认值不同(或者如果没有默认值)且存储的说明符为True,则保存属性的值。否则,不保存属性的值。