2013-01-31 46 views
2

我寫了簡單的代碼(見下文):帶有事件的TCollectionItem的後裔。但是當我在對象檢查器中點擊OnDone事件時,我收到消息:TCollectionItem的後裔中的事件

「無法爲未命名組件創建方法」。

這段代碼有什麼問題?

unit MainComponent2; 

interface 

uses Windows, SysUtils, Classes; 

type 
    TMyField = class(TCollectionItem) 
    private 
    FName: string; 
    FOnDone: TNotifyEvent; 
    FText: string; 
    protected 
    function GetDisplayName : String; override; 
    public 
    constructor Create(ACollection: TCollection);override; 
    function GetNamePath: string;override; 
    published 
    property Name: string read FName write FName; 
    property Text: string read FText write FText; 
    property OnDone: TNotifyEvent read FOnDone write FOnDone; 
    end; 

    TMyFields = class(TOwnedCollection) 
    private 
    function GetItem(Index: Integer): TMyField; 
    procedure SetItem(Index: Integer; const Value: TMyField); 
    protected 
    procedure Update(Item: TmyField);reintroduce; 
    public 
    constructor Create(AOwner: TComponent); 
    function Add: TMyField; 
    function Insert(Index: Integer): TMyField; 
    property Items[Index: Integer]: TMyField read GetItem write SetItem; default; 
    end; 


    TMainComponent2 = class(TComponent) 
    private 
    FMyFields: TMyFields; 
    function GetItem(index: integer): TMyField; 
    procedure SetItem(index: integer; const Value: TMyField); 
    procedure SetMyFields(const Value: TMyFields); 
    public 
    constructor Create(AOwner: TComponent);override; 
    destructor Destroy;override; 

    property Items[index: integer]: TMyField read GetItem write SetItem; 
    published 
    property MyFields: TMyFields read FMyFields write SetMyFields; 
    end; 

procedure Register; 

implementation 

{ TMainComponent2 } 

constructor TMainComponent2.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    FMyFields := TMyFields.Create(AOwner); 
end; 

destructor TMainComponent2.Destroy; 
begin 
    FMyFields.Free; 
    inherited; 
end; 

function TMainComponent2.GetItem(index: integer): TMyField; 
begin 
    result := FMyFields.Items[index] as TMyField; 
end; 

procedure TMainComponent2.SetItem(index: integer; const Value: TMyField); 
begin 
    FMyFields.Items[index] := Value; 
end; 

procedure TMainComponent2.SetMyFields(const Value: TMyFields); 
begin 
    FMyFields.Assign(Value); 
end; 

{ TMyField } 

constructor TMyField.Create(ACollection: TCollection); 
begin 
    inherited Create(ACollection); 
    FName := ClassName + IntToStr(ID); 
end; 

function TMyField.GetDisplayName: String; 
begin 
    result := FName; 
end; 

function TMyField.GetNamePath: string; 
begin 
    Result := Format('%s%d',['MyField', Index]) 
end; 

{ TMyFields } 

function TMyFields.Add: TMyField; 
begin 
    result := (inherited Add) as TMyField; 
end; 

constructor TMyFields.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner, TMyField); 
end; 

function TMyFields.GetItem(Index: Integer): TMyField; 
begin 
    result := (inherited GetItem(Index)) as TMyField; 
end; 

function TMyFields.Insert(Index: Integer): TMyField; 
begin 
    result := (inherited Insert(Index)) as TMyField; 
end; 

procedure TMyFields.SetItem(Index: Integer; const Value: TMyField); 
begin 
    inherited SetItem(Index, Value); 
end; 

procedure TMyFields.Update(Item: TmyField); 
begin 
    inherited Update(Item); 
end; 

procedure Register; 
begin 
    RegisterComponents('MyComponents', [TMainComponent2]); 
end; 

end. 

回答

5

你忘了包括TMyField繼承的名稱路徑:

function TMyField.GetNamePath: string; 
begin 
    Result := inherited GetNamePath + Format('MyField%d',[Index]); 
end; 

而且,你已經給了MyFields財產錯所有者。使用Self而不是AOwnerAOwner是您放置組件的窗體。

constructor TMainComponent2.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    FMyFields := TMyFields.Create(Self); 
end; 

B.t.w.你爲什麼再次引入TMyFields.Update?這打破了繼承鏈。儘可能使用override,或添加其他方法。

+0

謝謝!它的工作原理。我使用reintroduce,因爲當我使用覆蓋編譯器說:「更新不同於以前的聲明」。 TOwnedCollection有更新(Item:TCollectionItem)。我有更新(Item:TMyField)。 –

+1

您不必:'TMyField'是'TCollectionItem'。如果你需要把它作爲'TMyField'來處理,那麼就在'Update'方法中將其強制轉換。 – NGLN

+0

請考慮[接受此答案](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)。 – NGLN