我正在尝试创建像TImage这样的VCL组件,这样我就可以添加不同数量的不同大小的TPictures。 目标是能够通过属性列表中的VCL编辑器分配该数量的TPictures。
delphi component property: TObjectList<TPicture>我们在这里得出结论,应该使用TCollection和TCollectionItems。这就是我现在要做的事情,但在我最终遇到编译错误之前很多次:&#34;已发布的属性&#39;图片&#39;不能是ARRAY类型&#34;在这一行:
property Pictures[Index: Integer]: TPic read GetPic write SetPic;
unit ImageMultiStates;
interface
uses
Vcl.Graphics, Vcl.StdCtrls, System.SysUtils, System.Classes, Vcl.Controls, Vcl.ExtCtrls, Forms, Generics.Collections;
type
TPic = class(TCollectionItem)
private
FPicture: TPicture;
public
procedure Assign(Source: TPersistent); override;
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
published
property Picture: TPicture read FPicture write FPicture;
end;
TPictures = class(TCollection)
private
function GetPic(Index: Integer): TPic;
procedure SetPic(Index: Integer; APicture: TPic);
public
constructor Create;
published
property Pictures[Index: Integer]: TPic read GetPic write SetPic;
end;
TImageMultiStates = class(TImage)
private
FPictures: TPictures;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Activate(Index: Integer);
end;
procedure Register;
implementation
constructor TPic.Create(Collection: TCollection);
begin
inherited Create(Collection);
end;
destructor TPic.Destroy;
begin
FPicture.Free;
inherited Destroy;
end;
procedure TPic.Assign(Source: TPersistent);
begin
FPicture.Assign(Source);
end;
constructor TPictures.Create;
begin
inherited Create(TPic);
end;
procedure TPictures.SetPic(Index: Integer; APicture: TPic);
begin
Items[Index].Assign(APicture);
end;
function TPictures.GetPic(Index: Integer): TPic;
begin
Result := TPic(inherited Items[Index]);
end;
constructor TImageMultiStates.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
destructor TImageMultiStates.Destroy;
begin
FPictures.Free;
inherited Destroy;
end;
procedure TImageMultiStates.Activate(Index: Integer);
begin
Picture.Assign(FPictures.Items[Index]);
end;
procedure Register;
begin
RegisterComponents('Standard', [TImageMultiStates]);
end;
end.
由于似乎没有人希望抛出这个错误,可能它与我安装的组件有关?我使用内部GetIt包管理器来安装Jedi代码库2.8,Jedi Visual Component Library和PNGComponents 1.0。就与TImage相关的组件而言,我想这是关于它的。也许其中一个用一些时髦的东西覆盖我的一些TImage内容......
答案 0 :(得分:3)
我进行了一些实验并从TPicturePanel
派生了一个TPanel
。它有一个Pictures
属性,TPictures
,TOwnedCollection
的后代,包含TPics
。每个TPic
都有Picture
个属性。我可以安装此组件,它允许我使用所谓的集合编辑器编辑Pictures
集合,它允许您添加或删除TPic
个实例。如果您在收藏编辑器中选择TPic
,则可以将图片分配到其Picture
属性,即从文件加载等。
以下是TPicturePanel
的工作代码。您可以在此之后为组件建模:
unit PicturePanels;
interface
uses
System.SysUtils, System.Classes, Vcl.Controls, Vcl.ExtCtrls, Vcl.Graphics;
type
TPic = class(TCollectionItem)
private
FPicture: TPicture;
procedure SetPicture(const Value: TPicture);
public
procedure Assign(Source: TPersistent); override;
constructor Create(AOwner: TCollection); override;
destructor Destroy; override;
published
property Picture: TPicture read FPicture write SetPicture;
end;
TPictures = class(TOwnedCollection)
private
function GetItem(Index: Integer): TPic;
procedure SetItem(Index: Integer; const Value: TPic);
public
constructor Create(AOwner: TPersistent);
property Items[Index: Integer]: TPic read GetItem write SetItem;
end;
TPicturePanel = class(TPanel)
private
FPictures: TPictures;
procedure SetPictures(const Value: TPictures);
published
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Pictures: TPictures read FPictures write SetPictures;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TPicturePanel]);
end;
{ TPicturePanel }
constructor TPicturePanel.Create(AOwner: TComponent);
begin
inherited;
FPictures := TPictures.Create(Self);
end;
destructor TPicturePanel.Destroy;
begin
FPictures.Free;
inherited;
end;
procedure TPicturePanel.SetPictures(const Value: TPictures);
begin
FPictures.Assign(Value);
end;
{ TPic }
procedure TPic.Assign(Source: TPersistent);
begin
inherited;
if Source is TPic then
FPicture.Assign(TPic(Source).FPicture);
end;
constructor TPic.Create(AOwner: TCollection);
begin
inherited;
FPicture := TPicture.Create;
end;
destructor TPic.Destroy;
begin
FPicture.Free;
inherited;
end;
procedure TPic.SetPicture(const Value: TPicture);
begin
FPicture.Assign(Value);
end;
{ TPictures }
constructor TPictures.Create(AOwner: TPersistent);
begin
inherited Create(AOwner, TPic);
end;
function TPictures.GetItem(Index: Integer): TPic;
begin
Result := inherited GetItem(Index) as TPic;
end;
procedure TPictures.SetItem(Index: Integer; const Value: TPic);
begin
inherited SetItem(Index, Value);
end;
end.
答案 1 :(得分:0)
您的索引属性使用看起来像返回数组的语法,但它不会这样做。 pictures
属性返回索引TPic
。它一次只能返回一个TPic
。
如果你想返回一个数组,你必须这么说:
function GetPictures: TArray<TPicture>;
procedure SetPictures(const value: TArray<TPicture>);
property Pictures: TArray<TPicture> read GetPictures write SetPictures;
//GetPictures might look something like this:
function TMyClass.GetPictures: TArray<TPicture>;
var
i: integer;
begin
SetLength(Result, Self.FPictureCount);
for i:= 0 to FPictureCount - 1 do begin
Result[i]:= GetMyPicture[i];
end;
end;
我不确定您的TPic系列是如何工作的,因此您必须根据自己的需要进行调整
如果你愿意的话,显然你可以拥有TArray<TArray<TPicture>>
(又名:array of array of TPicture
)。