2016-12-27 81 views
5

我正在製作一個Delphi vcl組件,該組件類有一個'圖像'屬性,可以讓我選擇一個TImagelist。德爾福組件設計 - 從子屬性組件獲取屬性

組件類也有一個子屬性「按鈕」,它本身有一個imageindex屬性。

我已經編寫了imageindex屬性的組件編輯器,以便我可以從圖像列表中選擇按鈕上的圖像;我之前已經在其他組件中完成了這項工作,但現在我面臨的問題是我需要從「按鈕」子類事件中的事件中獲取基類的圖像屬性。

所以,基類的組件具有以下屬性:

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

的按鈕類有該屬性:

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

我註冊ImageIndex屬性在一個單獨的單元中的屬性編輯器,爲了選擇一個圖像,但在這種情況下,我需要從組件的基類獲取圖像列表,我如何從這個子屬性獲取這個屬性?

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; 

所有類:

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; 

回答

8

當暴露在設計時收集,使用TOwnedCollection,而不是直接TCollection。這有助於DFM流式傳輸,而無需編寫額外的代碼來啓用它。

TCollectionItem有一個Collection屬性,而該屬性又有Owner方法,TOwnedCollection實現。這樣,您可以從代碼中的按鈕到其擁有的組框。

試試這個:

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; 
+1

感謝優秀的和明確的示例代碼雷米,這似乎工作得很好,現在我明白了該系統。 –