情况就是这样:
3 involucrated:myComponent组件,祖先形式和子表单:(已编辑)
MyComponent的:
unit Component1;
interface
uses
System.SysUtils, System.Classes, Vcl.Dialogs;
type
TMyComponent = class(TComponent)
private
{ Private declarations }
procedure Something(i: Integer);
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
published
{ Published declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TMyComponent]);
end;
{ TMyComponent }
constructor TMyComponent.Create(AOwner: TComponent);
var
i: integer;
begin
inherited Create(AOwner);
if AOwner.ComponentCount > 0 then
for i := 0 to AOwner.ComponentCount -1 do
Something(i);
end;
procedure TMyComponent.Something(i: Integer);
var
txt: string;
begin
txt := Format('Owner Name is %s, Owner Class is %s, ComponentCount is %d,'+
'myIndex is %d, My name is %s, my class is %s',
[Owner.Name, Owner.ClassName, Owner.ComponentCount, i, Owner.Components[i].Name,
Owner.Components[i].ClassName]);
ShowMessage('Hello '+txt);
end;
end.
祖先形式:
unit Ancestor;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Component1;
type
TmyAncestor = class(TForm)
MyComponent1: TMyComponent;
private
{ Private declarations }
public
{ Public declarations }
end;
var
myAncestor: TmyAncestor;
implementation
{$R *.dfm}
end.
儿童表格:
unit TheChild;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Ancestor, Vcl.StdCtrls, Component1;
type
TmyChild = class(TmyAncestor)
edt1: TEdit;
private
{ Private declarations }
public
{ Public declarations }
end;
var
myChild: TmyChild;
implementation
{$R *.dfm}
end.
dpr:
program InheritanceTest;
uses
Vcl.Forms,
Ancestor in 'Ancestor.pas' {myAncestor},
TheChild in 'TheChild.pas' {myChild};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TmyChild, myChild);
Application.Run;
end.
子表单从祖先表单继承myComponent。
创建时,子窗体会触发TMyComponent.Create()
构造函数,但AOwner.ComponentCount
会看到祖先ComponentCount
而不是孩子的ComponentCount
。
消息(来自myComponent.Something()
方法)显示:
" Hello Owner Name是myAncestor,Owner类是TMyChild,ComponentCount是1,myIdex是0,我的名字是,我的类是TMyComponent"
组件在子窗体中看不到edt1
组件!!!
如何查看正确的ComponentCount?
答案 0 :(得分:0)
您的TMyComponent
对象看不到TEdit
对象,因为该对象尚未创建。您的TMyComponent
对象首先被创建,因为它首先出现在子窗体的DFM中。
如果您希望组件检测到在创建组件后何时创建TEdit
,则可以让组件覆盖虚拟Notification()
方法。将组件添加到所有者(或从其中删除)时,所有者会向其拥有的所有组件广播opInsert
(或opRemove
)通知。由于您的TMyComponent
和TEdit
个对象具有相同的所有者,因此当您在表单的自有组件列表中添加opInsert
时,您的组件将收到TEdit
通知。
例如:
unit Component1;
interface
uses
System.SysUtils, System.Classes, Vcl.Dialogs;
type
TMyComponent = class(TComponent)
private
{ Private declarations }
procedure Something(const FromWhere: string; Index: Integer);
protected
{ Protected declarations }
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
published
{ Published declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TMyComponent]);
end;
{ TMyComponent }
constructor TMyComponent.Create(AOwner: TComponent);
var
i: integer;
begin
inherited Create(AOwner);
if AOwner <> nil then
begin
for i := 0 to AOwner.ComponentCount-1 do
Something(`Create`, i);
end;
end;
procedure TMyComponent.Notification(AComponent: TComponent; Operation: TOperation);
var
i: integer;
begin
inherited;
if (Operation = opInsert) and (AComponent <> Self) and (AComponent.Owner = Owner) then
Something('Notification', AComponent.ComponentIndex);
end;
procedure TMyComponent.Something(const FromWhere: string; Index: Integer);
var
txt: string;
begin
txt := Format('Owner Name is %s, Owner Class is %s, ComponentCount is %d, myIndex is %d, My name is %s, my class is %s',
[Owner.Name, Owner.ClassName, Owner.ComponentCount, Index, Owner.Components[Index].Name, Owner.Components[Index].ClassName]);
ShowMessage(FromWhere + ',' + txt);
end;
end.