Delphi 组件设计 - 从 sub属性 的组件中获取 属性

Delphi component design - get property from component from subproperty

我正在制作一个 Delphi vcl 组件,组件 class 有一个 'images' 属性 让我 select 一个 TImagelist。

组件 class 也有一个子 属性 'buttons' 本身有一个 imageindex 属性.

我已经为 imageindex 属性 编写了一个组件编辑器,这样我就可以 select 在图像列表的按钮上添加图像;我以前在其他组件中做过这个,但我现在面临的问题是我需要从 'buttons' 子 [=] 中的事件中获取基础 class 的图像 属性 33=]事件。

因此,组件的基础 class 具有以下属性:

property Buttons: TFlexButtons read FButtons write FButtons;
property Images: TCustomImageList read FImages write SetImages;

按钮 class 有这个 属性:

property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1;

我在 ImageIndex 属性 的单独单元中注册了一个 属性 编辑器,以便选择图像,但在这种情况下,我需要从 baseclass 的组件,我如何从这个子 属性 得到这个 属性?

function TImageIndexProperty.GetImageListAt(Index: Integer): TCustomImageList;
var APersistent: TPersistent;
begin
  APersistent := GetComponent(Index);
  if APersistent is TFlexButton then
    Result := ??????????.Images //how do i refer to the images property of the component here?
  else
    Result := nil;
end;

全部class是:

TFlexButton = class(TCollectionItem)
private
  FWidth: Word;
  FCaption: string;
  FHeight: Word;
  FImageIndex: TImageIndex;
  procedure SetCaption(const Value: string);
  procedure SetHeight(const Value: Word);
  procedure SetWidth(const Value: Word);
  procedure SetImageIndex(const Value: TImageIndex);
public
  constructor Create(AOwner: TComponent);
  destructor Destroy; override;
published
  property Caption: string read FCaption write SetCaption;
  property Height: Word read FHeight write SetHeight;
  property Width: Word read FWidth write SetWidth;
  property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1;
end;

TFlexButtons = class(TCollection)
private
  function GetItem(Index: Integer): TFlexButton;
public
  function Add: TFlexButton;
  property Item[index: Integer]: TFlexButton read GetItem;
end;

TFlexButtonGroupBox = class(TcxGroupBox)
private
  FDataLink: TFieldDataLink;
  FAbout: string;
  FAlignment: TAlignment;
  FEnabled: Boolean;
  FButtons: TFlexButtons;
  FImages: TCustomImageList;
  FSql: TStrings;
  FAutosize: Boolean;
  procedure SetAlignment(const Value: TAlignment);
  function GetDataField: string;
  function GetDataSource: TdataSource;
  procedure SetDataField(const Value: string);
  procedure SetDataSource(const Value: TdataSource);
  procedure DataChange(Sender: TObject);
  procedure SetEnabled(const Value: Boolean);
  procedure SetImages(const Value: TCustomImageList);
  procedure SetSql(const Value: TStrings);
  procedure SetAutosize(const Value: Boolean);
protected
public
  procedure Loaded; override;
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override;
published
  property DataField: string read GetDataField write SetDataField;
  property DataSource: TdataSource read GetDataSource write SetDataSource;
  property Enabled: Boolean read FEnabled write SetEnabled;
  property Autosize: Boolean read FAutosize write SetAutosize;
  property About: string read FAbout write FAbout;
  property Buttons: TFlexButtons read FButtons write FButtons;
  property Images: TCustomImageList read FImages write SetImages;
  property Alignment: TAlignment read FAlignment write SetAlignment;
  property Sql: TStrings read FSql write SetSql;
end;

在设计时公开集合时,请使用 TOwnedCollection 而不是直接使用 TCollection。这有助于 DFM 流式传输,而无需编写额外的代码来启用它。

TCollectionItem 有一个 TOwnedCollection 实现的 Collection property, which in turn has an Owner 方法。这样,您就可以在代码中从一个按钮获取到它所属的分组框。

试试这个:

TFlexButton = class(TCollectionItem)
private
  ...
public
  constructor Create(ACollection: TCollection); override;
end;

TFlexButtonGroupBox = class;

TFlexButtons = class(TOwnedCollection)
private
  ...
public
  constructor Create(AOwner: TFlexButtonGroupBox); reintroduce;
  ...
end;

TFlexButtonGroupBox = class(TcxGroupBox)
private
  ...
  procedure SetButtons(AValue: TFlexButtons;
public
  constructor Create(AOwner: TComponent); override;
  ...
published
  ...
  property Buttons: TFlexButtons read FButtons write SetButtons;
  ...
end;

constructor TFlexButton.Create(ACollection: TCollection);
begin
  inherited;
  ...
end;

constructor TFlexButtons.Create(AOwner: TFlexButtonGroupBox);
begin
  inherited Create(AOwner, TFlexButton);
  ...
end;

constructor TFlexButtonGroupBox.Create(AOwner: TComponent);
begin
  inherited;
  FButtons := TFlexButtons.Create(Self);
  ...
end;

procedure TFlexButtonGroupBox.SetButtons(AValue: TFlexButtons;
begin
  FButtons.Assign(AValue);
end;

function TImageIndexProperty.GetImageListAt(Index: Integer): TCustomImageList;
begin
  Result := ((GetComponent(Index) as TFlexButton).Collection.Owner as TFlexButtonGroupBox).Images;
end;