当“...”单击代表另一个 TCollection 的 TCollectionItem 属性 时没有反应

No reaction when "..." clicked on a TCollectionItem property that represents another TCollection

我从来没有遇到过需要它的情况,这是我第一次尝试将 TCollection 作为另一个 TCollectionTCollectionItem。 一切都编译正常,但是当点击 TCollectionItemTCollection 属性 后面的三个点时没有反应,即。包含该子TCollection列表的对话框不会出现。

我的印象是,因为不需要花哨的 属性 编辑器(sub-TCollection 只包含具有 string 和 [=20= 的项目] 属性),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 的最短路径,我将不胜感激。

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

我还建议为 TBitmapItemTagsTBitmaps 定义显式构造函数。

您还需要向 object-based 属性中添加一些 setter 方法,否则您可能会在运行时发生内存泄漏。您的 setter 应该在您的 object 上调用 Assign() 以将 属性 值从一个 object 复制到另一个。 TCollection 已经为您实现了 Assign(),但您必须在 collection 项中实现 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;