I've implemented this using TCollection & TCollectionItem descendants.
Everything appears ok so far, except that I cannot assign an OnClick event
to the buttons within the IDE object inspector.
When I try this, I get "Cannot create a method for an unnamed component".
Any suggestions as to how to fix this ?
My source code is below :
unit BtnPanel;
interface
uses
SysUtils, Classes, RzPanel, RzButton;
type
TBtnPanel = class;
TBtnItem = class(TCollectionItem)
private
{ Private declarations }
FButton:TRzButton;
procedure SetCaption(Value:string);
function GetCaption:string;
procedure SetName(Value:string);
function GetName:string;
procedure SetOnClick(Value:TNotifyEvent);
function GetOnClick:TNotifyEvent;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(Collection:TCollection); override;
destructor Destroy; override;
procedure Assign(Source:TPersistent); override;
published
{ Published declarations }
property Name:string read GetName write SetName;
property Caption:string read GetCaption write SetCaption;
property OnClick:TNotifyEvent read GetOnClick write SetOnClick;
end;
TBtns = class(TCollection)
private
{ Private declarations }
FPanel:TBtnPanel;
function GetItem(Index: Integer): TBtnItem;
procedure SetItem(Index: Integer; Value: TBtnItem);
protected
{ Protected declarations }
procedure Update(Item:TCollectionItem); override;
public
{ Public declarations }
constructor Create(Panel: TBtnPanel);
function Add:TBtnItem;
property Items[Index:integer]:TBtnItem read GetItem write SetItem;
default;
published
{ Published declarations }
end;
TBtnPanel = class(TRzPanel)
private
{ Private declarations }
FBtns : TBtns;
procedure SetBtns(Value:TBtns);
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner:TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
property Btns:TBtns read FBtns write SetBtns;
end;
procedure Register;
implementation
{ TBtnItem }
procedure TBtnItem.Assign(Source: TPersistent);
begin
//
end;
constructor TBtnItem.Create(Collection: TCollection);
begin
inherited Create(Collection);
FButton := TRzButton.Create(TBtns(Collection).FPanel);
FButton.Parent := TBtns(Collection).FPanel;
end;
destructor TBtnItem.Destroy;
begin
FButton.Free;
inherited Destroy;
end;
function TBtnItem.GetCaption: string;
begin
Result := FButton.Caption;
end;
function TBtnItem.GetName: string;
begin
Result := FButton.Name;
end;
function TBtnItem.GetOnClick: TNotifyEvent;
begin
Result := FButton.OnClick;
end;
procedure TBtnItem.SetCaption(Value: string);
begin
FButton.Caption := Value;
end;
procedure TBtnItem.SetName(Value: string);
begin
FButton.Name := Value;
end;
procedure TBtnItem.SetOnClick(Value: TNotifyEvent);
begin
FButton.OnClick := Value;
end;
{ TBtns }
function TBtns.Add: TBtnItem;
begin
Result := TBtnItem(inherited Add);
end;
constructor TBtns.Create(Panel: TBtnPanel);
begin
inherited Create(TBtnItem);
FPanel := Panel;
end;
function TBtns.GetItem(Index: Integer): TBtnItem;
begin
Result := TBtnItem(inherited GetItem(Index));
end;
procedure TBtns.SetItem(Index: Integer; Value: TBtnItem);
begin
inherited SetItem(Index, Value);
end;
procedure TBtns.Update(Item: TCollectionItem);
begin
if Item <> nil then begin
//
end;
end;
{ TBtnPanel }
constructor TBtnPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FBtns := TBtns.Create(self);
end;
destructor TBtnPanel.Destroy;
begin
FBtns.Free;
inherited Destroy;
end;
procedure TBtnPanel.SetBtns(Value: TBtns);
begin
FBtns.Assign(Value);
end;
procedure Register;
begin
RegisterComponents('Samples',[TBtnPanel]);
end;
end.
The class TBtns should inherits from TOwnedCollection instead of TColletion:
TBtns = class(TOwnedCollection)
And then adjust your constructor to match the ancestor's create method:
constructor TBtns.Create(Panel: TBtnPanel);
begin
inherited Create(Panel, TBtnItem);
FPanel := Panel;
end;
That's all!
I hope this help.
Jeferson Oliveira
Brazil
Many thanks. It works now !!