2016-12-27 33 views
5

Tôi đang tạo thành phần vcl Delphi, lớp thành phần có thuộc tính 'hình ảnh' cho phép tôi chọn một TImagelist.Thiết kế thành phần Delphi - lấy thuộc tính từ thành phần từ subproperty

Lớp thành phần cũng có nút 'cấp phụ' có chính thuộc tính imageindex.

Tôi đã viết một trình soạn thảo thành phần cho thuộc tính imageindex để tôi có thể chọn hình ảnh trên các nút từ hình tượng; tôi đã làm điều này trong các thành phần khác trước đây nhưng vấn đề tôi đang phải đối mặt bây giờ là tôi cần để có được các tài sản hình ảnh của lớp cơ sở từ sự kiện trong sự kiện lớp con 'nút'.

Vì vậy, các lớp cơ sở của các thành phần có các đặc tính này:

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

Lớp nút có khách sạn này:

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

tôi đăng ký một trình soạn thảo bất động sản trong một đơn vị riêng biệt cho các tài sản ImageIndex , để chọn một hình ảnh nhưng trong sự kiện này tôi cần phải có được những người tưởng tượng từ baseclass của các thành phần, làm thế nào để tôi có được tài sản này từ tài sản phụ này?

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; 

Tất cả các lớp:

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; 

Trả lời

8

Khi phơi bày một bộ sưu tập lúc thiết kế, sử dụng TOwnedCollection thay vì TCollection trực tiếp. Điều này tạo điều kiện cho DFM streaming mà không cần phải viết thêm mã để kích hoạt nó.

TCollectionItem có thuộc tính Collection, lần lượt có phương thức OwnerTOwnedCollection thực hiện. Bằng cách này, bạn có thể nhận được từ một nút để hộp nhóm sở hữu của nó trong mã.

Hãy thử điều này:

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

Cảm ơn đã xuất sắc và rõ ràng mã ví dụ Remy, điều này dường như chỉ làm việc tốt và bây giờ tôi hiểu hệ thống. –

Các vấn đề liên quan