0

我从来没有遇到过需要它的情况,这是我第一次尝试TCollection拥有TCollectionItem另一个TCollection. TCollectionItem这一切都编译得很好,但是当单击'TCollection属性后面的三个点时没有反应,即。TCollection不会出现包含该子列表的对话框。

我的印象是,由于不需要花哨的属性编辑器(子TCollection只携带具有 astring和 asingle属性的项目),IDE 几乎会自动处理它。

显然情况并非如此,或者我正在监督显而易见的事情,这是一种慢性病。

实现(运行时)单元有这个:

type

  TBitmapItemTag = class(TCollectionItem)
  private
    FTagName: string;
    FTagFloat: Single;
  published
    property TagName: string read FTagName write FTagName;
    property TagFloat: Single read FTagFloat write FTagFloat;
  end;

  TBitmapItemTags = class(TOwnedCollection)

  end;

  TBitmapItem = class(TCollectionItem)
  private
    FBitmap: TBitmap;
    FBitmapItemTags: TBitmapItemTags;
  public
    constructor Create(Collection: TCollection); override;
    destructor Destroy; override;
  published
    property Bitmap: TBitmap read FBitmap write FBitmap;
    property Tags: TBitmapItemTags read FBitmapItemTags write FBitmapItemTags;
  end;

  TBitmaps = class(TCollection)

  end;

  TBitmapCollection = class(TComponent)
  private
    FBitmaps: TBitmaps;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Bitmaps: TBitmaps read FBitmaps write FBitmaps;
  end;

implementation

{ TBitmapItem }

constructor TBitmapItem.Create(Collection: TCollection);
begin
  inherited Create(Collection);
  FBitmap := TBitmap.Create(0, 0);
  FBitmapItemTags := TBitmapItemTags.Create(Self,TBitmapItemTag);
end;

destructor TBitmapItem.Destroy;
begin
  FBitmap.Free;
  FBitmapItemTags.Free;
  inherited;
end;

{ TBitmapCollection }

constructor TBitmapCollection.Create(AOwner: TComponent);
begin
  inherited;
  FBitmaps := TBitmaps.Create(TBitmapItem);
end;

destructor TBitmapCollection.Destroy;
begin
  FBitmaps.Free;
  inherited;
end;

Register过程在设计时单元中实现,并且只调用该RegisterComponents过程。RegisterPropertyEditor并进行了一些无济于事的懒惰尝试。

如果有人能指出我的最短路径以便 IDE 识别TBitmapItemTag TCollectionItem,我将不胜感激。

4

1 回答 1

2

您需要更改TBitmaps为派生自TOwnedCollection而不是TCollection.

我还建议为TBitmapItemTags和定义显式构造函数TBitmaps

您还需要向基于对象的属性添加一些 setter 方法,否则您可能会在运行时出现内存泄漏。您的 setter 应该调用Assign()您的对象以将属性值从一个对象复制到另一个对象。 TCollection已经Assign()为您实施,但您必须Assign()在您的收藏品中实施。

尝试这个:

type
  TBitmapItemTag = class(TCollectionItem)
  private
    FTagName: string;
    FTagFloat: Single;
  public
    procedure Assign(ASource: TPersistent); override;
  published
    property TagName: string read FTagName write FTagName;
    property TagFloat: Single read FTagFloat write FTagFloat;
  end;

  TBitmapItem = class;

  TBitmapItemTags = class(TOwnedCollection)
  public
    constructor Create(AOwner: TBitmapItem); reintroduce;
  end;

  TBitmapItem = class(TCollectionItem)
  private
    FBitmap: TBitmap;
    FTags: TBitmapItemTags;
    procedure SetBitmap(AValue: TBitmap);
    procedure SetTags(AValue: TBitmapItemTags);
  public
    constructor Create(Collection: TCollection); override;
    destructor Destroy; override;
    procedure Assign(ASource: TPersistent); override;
  published
    property Bitmap: TBitmap read FBitmap write SetBitmap;
    property Tags: TBitmapItemTags read FTags write SetTags;
  end;

  TBitmapCollection = class;

  TBitmaps = class(TOwnedCollection)
  public
    constructor Create(AOwner: TBitmapCollection); reintroduce;
  end;

  TBitmapCollection = class(TComponent)
  private
    FBitmaps: TBitmaps;
    procedure SetBitmaps(AValue: TBitmaps);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Bitmaps: TBitmaps read FBitmaps write SetBitmaps;
  end;

{ TBitmapTagItem }

procedure TBitmapItemTag.Assign(ASource: TPersistent);
begin
  if ASource is TBitmapItemTag then
  begin
    FTagName := TBitmapItemTag(ASource).TagName;
    FTagFloat := TBitmapItemTag(ASource).TagFloat;
  end
  else
    inherited;
end;

{ TBitmapItemTags }

constructor TBitmapItemTags.Create(AOwner: TBitmapItem);
begin
  inherited Create(AOwner, TBitmapItemTag);
end;

{ TBitmapItem }

constructor TBitmapItem.Create(Collection: TCollection);
begin
  inherited Create(Collection);
  FBitmap := TBitmap.Create(0, 0);
  FTags := TBitmapItemTags.Create(Self);
end;

destructor TBitmapItem.Destroy;
begin
  FBitmap.Free;
  FTags.Free;
  inherited;
end;

procedure TBitmapItem.Assign(ASource: TPersistent);
begin
  if ASource is TBitmapItem then
  begin
    FBitmap.Assign(TBitmapItem(ASource).Bitmap);
    FTags.Assign(TBitmapItem(ASource).Tags);
  end
  else
    inherited;
end;

procedure TBitmapItem.SetBitmap(AValue: TBitmap);
begin
  FBitmap.Assign(AValue);
end;

procedure TBitmapItem.SetTags(AValue: TBitmapItemTags);
begin
  FTags.Assign(AValue);
end;

{ TBitmaps }

constructor TBitmaps.Create(AOwner: TBitmapCollection);
begin
  inherited Create(AOwner, TBitmapItem);
end;

{ TBitmapCollection }

constructor TBitmapCollection.Create(AOwner: TComponent);
begin
  inherited;
  FBitmaps := TBitmaps.Create(Self);
end;

destructor TBitmapCollection.Destroy;
begin
  FBitmaps.Free;
  inherited;
end;

procedure TBitmapCollection.SetBitmaps(AValue: TBitmaps);
begin
  FBitmaps.Assign(AValue);
end;
于 2018-04-24T18:11:01.867 回答