组件的默认属性值

Posted

技术标签:

【中文标题】组件的默认属性值【英文标题】:Default property value of a component 【发布时间】:2013-05-30 04:23:12 【问题描述】:

我想知道是否可以为组件定义默认属性值。 换句话说,我想在设计时为系统中的每个 TDBGrid 设置一个唯一的名称(可能是 GUID),这可能吗? 还有另一种方法可以控制在运行时和设计时都有效的组件的唯一性。我关闭delphi后它也必须持续存在;例如组合框列表值。

提前致谢!

编辑

下面是代码,它不起作用:

type
  TMDBGrid = class(TDBGrid)
  private
    FUniqueName: String;
  protected
    function DefaultUniqueName: String;
    function GetUniqueName: String;
    procedure SetUniqueName(const AName: String);
  public
    constructor Create(AOwner: TComponent); override;
  published
    property UniqueName: String read GetUniqueName write SetUniqueName;
  end;

procedure Register;

implementation

uses uComponentUtils;

procedure Register;
begin
  RegisterComponents('MLStandard', [TMDBGrid]);
end;

 TMDBGrid 

constructor TMDBGrid.Create(AOwner: TComponent);
begin
  inherited;
  FUniqueName := DefaultUniqueName;
end;

function TMDBGrid.DefaultUniqueName: String;
begin
  Result := GenerateGUID(True);
end;

function TMDBGrid.GetUniqueName: String;
begin
  Result := '';
end;

procedure TMDBGrid.SetUniqueName(const AName: String);
begin
  FUniqueName := AName;
  if FUniqueName = '' then
    FUniqueName := DefaultUniqueName;
end;

function GenerateGUID(PlainText: Boolean = False): String;
var G: TGUID;
begin
  CreateGUID(G);
  Result:= GUIDToString(G);
  if PlainText then
    Result := MultiStringReplace(Result, ['','','[',']','-','.',' ','(',')'],
                                         ['','','','','','','','',''],
                                         [rfReplaceAll, rfIgnoreCase]);
end;

“它不起作用” 表示当 TDBGrid 添加到任何表单时,UNIQUENAME 为空。它应该有一个 GUID。

【问题讨论】:

您可以向组件添加一个属性,并在创建时为其赋予一个值,然后在 .dfm 文件中持久保存该值。 @DavidHeffernan 我的代码应该可以工作吗? 很难看出这将如何失败。它将保留在 .dfm 文件中。显然,它不会为在运行时创建的控件完成工作。如果您创建同一表单的多个实例,它也无法工作。您将在具有相同 ID 的不同表单上拥有控件。或者这就是你想要的?无论如何,让我们清楚。 “不工作”到底是什么意思? @DavidHeffernan 没关系,“很明显,运行时创建的控件无法完成工作。” @DavidHeffernan 最终组件应该像这样工作:每次将另一个组件添加到表单时,都会生成一个新的唯一名称。 【参考方案1】:

您对GetUniqueName 的实现不会返回任何内容。需要返回FUniqueName

function TMDBGrid.GetUniqueName: String;
begin
  Result := FUniqueName;
end;

或者您可以删除 getter 并将属性更改为:

property UniqueName: String read FUniqueName write SetUniqueName;

【讨论】:

我只是不相信我这样做了!超级FacePalm! 实际上,这里的重要教训是,将代码缩减到最小复制是多么重要。即使您发布的少量代码也有多余的代码。一旦你有了最小的复制,就很容易找到问题,因为要查看的代码更少。当问一个问题时,一个好的最小复制让我们的生活更轻松,这意味着你会有一个更好、更清晰的问题。 这个属性会在运行时被覆盖吗?如果 csDesigning in ComponentState then 我不应该添加 否,因为它将从 .dfm 文件中读取。第一次将组件放在表单上时,没有 .dfm 值可供读取,因此您将获得默认值,这是您在构造函数中设置的值。 除非属性具有default 值并且该值已设置。例如property MyProp: Integer read FMyProp write SetMyProp default 0; 如果此属性的值为0(默认值),则它甚至不会将其保存在 DFM 中。

以上是关于组件的默认属性值的主要内容,如果未能解决你的问题,请参考以下文章

Delphi 2009 - 在自定义 Delphi 组件中设置默认属性值

[react] 如果组件的属性没有传值,那么它的默认值是什么?

将属性默认值注入 3rd 方 Vue 组件

使用 TypeScript 3 扩展道具的 React 组件中的默认属性值

JSF 复合组件支持 bean EL 表达式作为必需属性的默认值失败,方法未知

React8 props的children校验默认值