首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >事件在TCollectionItem的后代中发生

事件在TCollectionItem的后代中发生
EN

Stack Overflow用户
提问于 2013-01-31 10:19:50
回答 1查看 735关注 0票数 2

我编写了简单的代码(参见下面):带有事件的TCollectionItem的后代。但是,当我在对象检查器中单击OnDone事件时,我会得到以下消息:

“无法为未命名组件创建方法”。

这个代码有什么问题?

代码语言:javascript
复制
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.
EN

回答 1

Stack Overflow用户

发布于 2013-01-31 11:00:15

您忘记包含TMyField的继承名称路径。

代码语言:javascript
复制
function TMyField.GetNamePath: string;
begin
  Result := inherited GetNamePath + Format('MyField%d',[Index]);
end;

另外,您为MyFields属性提供了错误的所有者。使用Self而不是AOwnerAOwner是删除组件的表单。

代码语言:javascript
复制
constructor TMainComponent2.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FMyFields := TMyFields.Create(Self);
end;

B.t.w.你为什么要重新引入TMyFields.Update?这破坏了继承链。在可能的情况下使用override,或者添加其他方法。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14623392

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档