gpt4 book ai didi

delphi - 集合编辑器未针对 TPersistent 属性中的 TCollection 属性打开

转载 作者:行者123 更新时间:2023-12-01 22:06:11 24 4
gpt4 key购买 nike

我有我的自定义集合属性,当它是我的组件的直接成员时,它工作得很好。

但我想将集合属性移动到组件内的 TPersistent 属性。现在问题来了,它不起作用:双击对象检查器中的集合属性通常会打开集合编辑器,但现在不再这样了。

首先 - 我应该将什么传递给 TPersistent 属性的构造函数?

TMyCollection = class(TCollection)
constructor Create(AOwner: TComponent); // TMyCollection constuctor
...

我无法传递 Self,那么我应该传递我的持久所有者吗?

constructor TMyPersistent.Create(AOwner: TComponent);
begin
inherited Create;
fOwner := AOwner;
fMyCollection := TMyCollection.Create(AOwner); // hmmm... doesn't make sense
end;

我想我错过了一些东西。如果需要更多代码,请评论这篇文章。

Da visualizationz

最佳答案

TCollection 的构造函数不需要 TComponent,而是 TCollectionItemClass。

您的集合现在是 TPersistent 属性的成员,而不是组件的直接成员,对于构造函数来说没有区别。

<小时/>

更新

不同之处在于所有权,但在 TPersistent 级别,应该通过 GetOwner 的正确实现来管理。 :

GetOwner returns the owner of an object. GetOwner is used by the GetNamePath method to find the owner of a persistent object. GetNamePath and GetOwner are introduced in TPersistent so descendants such as collections can appear in the Object Inspector.

您必须告诉 IDE,您的 TCollection 属性由 TPersistent 属性拥有,而 TPersistent 属性又由组件拥有。

The tutorial you are using关于此实现有几个错误:

  • 集合的所有者被声明为 TComponent,它应该是 TPersistent,
  • GetOwner 未针对 TPersistent 属性类实现,并且
  • 教程末尾显示的修复,指出 TPersistent 属性应该从 TComponent 继承,这是完全错误的;或者更好地说:是不实现 GetOwner 的解决方法。

它应该是这样的:

unit MyComponent;

interface

uses
Classes, SysUtils;

type
TMyCollectionItem = class(TCollectionItem)
private
FStringProp: String;
protected
function GetDisplayName: String; override;
public
procedure Assign(Source: TPersistent); override;
published
property StringProp: String read FStringProp write FStringProp;
end;

TMyCollection = class(TCollection)
private
FOwner: TPersistent;
function GetItem(Index: Integer): TMyCollectionItem;
procedure SetItem(Index: Integer; Value: TMyCollectionItem);
protected
function GetOwner: TPersistent; override;
public
constructor Create(AOwner: TPersistent);
function Add: TMyCollectionItem;
function Insert(Index: Integer): TMyCollectionItem;
property Items[Index: Integer]: TMyCollectionItem read GetItem
write SetItem;
end;

TMyPersistent = class(TPersistent)
private
FOwner: TPersistent;
FCollectionProp: TMyCollection;
procedure SetCollectionProp(Value: TMyCollection);
protected
function GetOwner: TPersistent; override;
public
procedure Assign(Source: TPersistent); override;
constructor Create(AOwner: TPersistent);
destructor Destroy; override;
published
property CollectionProp: TMyCollection read FCollectionProp
write SetCollectionProp;
end;

TMyComponent = class(TComponent)
private
FPersistentProp: TMyPersistent;
procedure SetPersistentProp(Value: TMyPersistent);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property PersistentProp: TMyPersistent read FPersistentProp
write SetPersistentProp;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Samples', [TMyComponent]);
end;

{ TMyCollectionItem }

procedure TMyCollectionItem.Assign(Source: TPersistent);
begin
if Source is TMyCollectionItem then
FStringProp := TMyCollectionItem(Source).FStringProp
else
inherited Assign(Source);
end;

function TMyCollectionItem.GetDisplayName: String;
begin
Result := Format('Item %d',[Index]);
end;

{ TMyCollection }

function TMyCollection.Add: TMyCollectionItem;
begin
Result := TMyCollectionItem(inherited Add);
end;

constructor TMyCollection.Create(AOwner: TPersistent);
begin
inherited Create(TMyCollectionItem);
FOwner := AOwner;
end;

function TMyCollection.GetItem(Index: Integer): TMyCollectionItem;
begin
Result := TMyCollectionItem(inherited GetItem(Index));
end;

function TMyCollection.GetOwner: TPersistent;
begin
Result := FOwner;
end;

function TMyCollection.Insert(Index: Integer): TMyCollectionItem;
begin
Result := TMyCollectionItem(inherited Insert(Index));
end;

procedure TMyCollection.SetItem(Index: Integer; Value: TMyCollectionItem);
begin
inherited SetItem(Index, Value);
end;

{ TMyPersistent }

procedure TMyPersistent.Assign(Source: TPersistent);
begin
if Source is TMyPersistent then
CollectionProp := TMyPersistent(Source).FCollectionProp
else
inherited Assign(Source);
end;

constructor TMyPersistent.Create(AOwner: TPersistent);
begin
inherited Create;
FOwner := AOwner;
FCollectionProp := TMyCollection.Create(Self);
end;

destructor TMyPersistent.Destroy;
begin
FCollectionProp.Free;
inherited Destroy;
end;

function TMyPersistent.GetOwner: TPersistent;
begin
Result := FOwner;
end;

procedure TMyPersistent.SetCollectionProp(Value: TMyCollection);
begin
FCollectionProp.Assign(Value);
end;

{ TMyComponent }

constructor TMyComponent.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FPersistentProp := TMyPersistent.Create(Self);
end;

destructor TMyComponent.Destroy;
begin
FPersistentProp.Free;
inherited Destroy;
end;

procedure TMyComponent.SetPersistentProp(Value: TMyPersistent);
begin
FPersistentProp.Assign(Value);
end;

end.

但是我可以说你也可以继承TOwnedCollection ,这使得 TMyCollection 的使用和声明变得更加简单:

  TMyCollection = class(TOwnedCollection)
private
function GetItem(Index: Integer): TMyCollectionItem;
procedure SetItem(Index: Integer; Value: TMyCollectionItem);
public
function Add: TMyCollectionItem;
function Insert(Index: Integer): TMyCollectionItem;
property Items[Index: Integer]: TMyCollectionItem read GetItem
write SetItem;
end;

关于delphi - 集合编辑器未针对 TPersistent 属性中的 TCollection 属性打开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6980401/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com