首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi 2009:组件对象属性默认值

Delphi 2009:组件对象属性默认值
EN

Stack Overflow用户
提问于 2015-12-11 18:26:49
回答 2查看 2K关注 0票数 2

如何设置组件对象属性值的默认值?

组件类代码:

代码语言:javascript
复制
unit CustomClass;

interface

uses
    Classes;

type
  TCustomClass = class;

  TConfiguration = class;

  TCustomClass = class (TComponent)
  private
    FConfiguration: TConfiguration;
    procedure SetConfiguration(const Value: TConfiguration);
  published
    property Configuration: TConfiguration read FConfiguration write SetConfiguration;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

  TConfiguration = class (TPersistent)
  private
    FDelay: Integer;
    FSize: Integer;
    procedure SetDelay(const Value: Integer);
    procedure SetSize(const Value: Integer);
  published
    property Delay: Integer read FDelay write SetDelay;
    property Size: Integer read FSize write SetSize;
  public
    procedure Assign(Source: TPersistent); override;
  end;

implementation

{ TCustomClass }

constructor TCustomClass.Create(AOwner: TComponent);
begin
  inherited;
  Configuration.FileName:= 'FileName';
  Configuration.Size := 10;
end;

destructor TCustomClass.Destroy;
begin
  Configuration.Free;
  inherited;
end;

procedure TCustomClass.SetConfiguration(const Value: TConfiguration);
begin
  FConfiguration.Assign(Value);
end;

{ TConfiguration }

procedure TConfiguration.Assign(Source: TPersistent);
begin
  inherited;
  Delay := (Source as TConfiguration).Delay;
  Size := (Source as TConfiguration).Size;
end;

procedure TConfiguration.SetDelay(const Value: Integer);
begin
  FDelay := Value;
end;

procedure TConfiguration.SetSize(const Value: Integer);
begin
  FSize := Value;
end;

end.

在我的IDE中,它将显示为对象属性被修改(粗体蓝色)。

我认为在TConfiguration类属性上创建默认和存储函数时,如下所示:

TConfiguration

代码语言:javascript
复制
interface

private
  function FileNameStored: Boolean;
published
  property FileName: string read FFileName write SetFileName stored FileNameStored;
  property Size: Integer read FSize write SetSize default 10;

implementation

function TConfiguration.FileNameStored: Boolean;
begin
  Result := FileName <> 'FileName';
end;

它将TConfiguration的属性涂成普通蓝色,而不是TCustomClass的配置属性,我不想在TCustomClass上设置它的默认值,因为TConfiguration可能在其他组件中使用。

然后,我还想:

TCustomClass

代码语言:javascript
复制
interface

private
  function ConfigurationStored: Boolean;
published
  property Configuration: TConfiguration read FConfiguration write SetConfiguration stored ConfigurationStored;

implementation

function TCustomClass.ConfigurationStored: Boolean;
begin
  Result := Configuration.FileName <> 'FileName' and
    Configuration.Size <> 10;
end;

但是,这只会将TCustomClass配置属性颜色设置为普通蓝色,而不是其属性。

答案

正如@RemyLebeau指出的(在第一个和最上面的答案中),代码中有错误。在该组件中,在这种情况下,我决定不为属性设置任何默认值。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-11 18:47:47

您的代码中有几个bug。

  1. 您的TCustomClass构造函数没有创建TConfiguration对象。你需要加一句: 构造函数TCustomClass.Create(AOwner: TComponent);开始继承;FConfiguration := TConfiguration.Create;// <--添加此FConfiguration.FileName :=‘文件名’;FConfiguration.Size := 10; 尽管如此,FileNameSize属性的赋值可能应该移动到TConfiguration构造函数,而不是TCustomClass构造函数。
  2. 不能用用户定义的默认值定义String属性,默认值始终是空字符串。因此,在创建组件时,您的FileName属性将始终以修改的形式出现,因为构造函数将为其分配一个非默认值。您的stored方法是正确的解决方案。或者,只需不指定默认的FileName at all,将其保留为空。如果用户没有指定显式FileName,则如果需要,您的代码可以假定默认值。 另一方面,Integer属性可以用用户定义的默认值定义.不过,您的Size属性并没有这样做。应该是(特别是如果将默认值的赋值移到TConfiguration构造函数中): 属性大小:整数读FSize写SetSize默认10;
  3. 您的TConfiguration.Assign()方法实现不正确。通过在复制值之前调用继承的Assign()方法,如果调用方将一个TConfiguration对象分配给另一个TConfiguration对象,则代码将始终在运行时引发TConfiguration异常。原因是因为基类TPersistent.Assign()实现只是调用Source.AssignTo(Self),而TConfiguration不覆盖AssignTo()方法,所以TPersistent.AssignTo()被调用,后者只调用Dest.AssignError(Self),这会引发异常。因此,如果Assign()实际上是TConfiguration对象,则不要调用继承的TConfiguration方法: 过程TConfiguration.Assign(来源: TPersistent);如果源是TConfiguration,则开始;然后开始FDelay := TConfiguration( Source ).Delay;FSize := TConfiguration(Source).Size;end .Size遗传;end;
票数 6
EN

Stack Overflow用户

发布于 2015-12-14 17:18:45

但是,这只会将TCustomClass Configuration属性的颜色设置为普通蓝色,而不是其属性。

那是故意的。存储说明符只对指定的属性起作用。

将类与窗体上的TFont属性进行比较。当ParentFontTrue时,Font属性将不会被存储。但是它的成员ColorName仍然不是默认的,因此它们看起来像是要被存储的。这是因为TFont对象不知道它的所有者,怎么可能呢?一次是画布的一部分,另一次是控件的一部分,或者根本没有所有者。在所有这些条件下,TFont对象应该是完全功能的,因此它不询问它的父对象应该如何运行。另一方面:父母也不应该询问孩子该如何表现。

现在回到您的场景:是否需要存储FileNameSize属性,应该在TConfiguration中处理。是否应该存储TCustomClassTCustomClass属性可能不取决于这些FileNameSize属性。如果存储了Configuration属性(粗体),但是它的所有成员都没有被存储(而不是粗体),那么最终就不会存储任何内容。如果您有一个ParentConfiguration属性,类似于ParentFont,则可以不存储Configuration属性。否则,离开它,让勇敢不再分散你的注意力。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34230173

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档