2016-12-27 91 views
5

Tworzy komponent vcl Delphi, klasa komponentów ma właściwość "images", która pozwala mi wybrać TImagelist.Projektowanie komponentów Delphi - pobierz właściwość z komponentu z podległości

Klasa elementów ma również "przyciski" podwłaściwości, która sama ma właściwość imageindex.

Napisałem edytor komponentów dla właściwości imageindex, dzięki czemu mogę wybrać obraz na przyciskach z listy obrazów; Zrobiłem to w innych składnikach wcześniej, ale problemem, z którym teraz borykam jest to, że muszę uzyskać właściwość obrazów klasy bazowej z zdarzenia w zdarzeniu podklasy 'buttons'.

Tak, klasa bazowa składnika ma następujące właściwości:

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

Klasa przyciski ma tę właściwość:

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

zarejestrować edytora własności w jednostce oddzielne dla właściwości imageIndex , w celu wybrania obrazu, ale w tym przypadku muszę uzyskać imagelist od klasy podstawowej komponentu, w jaki sposób uzyskać tę właściwość z tej właściwości podrzędnej?

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; 

Wszystkie zajęcia:

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; 

Odpowiedz

8

Podczas wystawiania kolekcji w czasie projektowania, użyj TOwnedCollection zamiast TCollection bezpośrednio. Ułatwia to strumieniowanie DFM bez konieczności pisania dodatkowego kodu, aby go włączyć.

TCollectionItem ma właściwość Collection, która z kolei ma metodę Owner, którą wdraża TOwnedCollection. W ten sposób można uzyskać od przycisku do jego pola grupy w kodzie.

Spróbuj tego:

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

Dzięki za doskonały i wyraźny przykład kodu Remy, to wydaje się działać dobrze i teraz rozumiem system. –