我正在编写一个组件,其中包含许多属性,这些属性将出现在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脚本文件。
答案 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,则保存属性的值。否则,不保存属性的值。