概述
为了更简单地将问题输入文本,我控件的继承看起来像这样:
TCustomListBox
> TMyCustomListBox
>TMyListBox
这样做的原因TMyCustomListBox
是TCustomListBox
通过添加一些我自己的新属性和方法进行扩展,然后我将拥有TMyListBox
从派生而来的其他组件TMyCustomListBox
,但也可能具有自己的属性和方法。
问题
我面临的问题是无法激发TMyListBox
我引入的方法TCustomListBox
。
考虑到这一点,下面是一个摘要片段TMyCustomListBox
,您可以在其中查看我添加的新方法类型(OnAddition):
type
TOnAdditionEvent = procedure(Sender: TObject; Index: Integer; Value: string) of object;
TMyCustomListBox = class(TCustomListBox)
private
FOnAddition: TOnAdditionEvent;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property OnAddition: TOnAdditionEvent read FOnAddition write FOnAddition;
property OnClick;
property OnDblClick;
// ...
end;
我将事件分配为:
if Assigned(FOnAddition) then
begin
FOnAddition(Self, SomeIndex, SomeValue);
end;
从上面调用:
procedure WndProc(var Message: TMessage); override;
现在我们有TMyListBox
:
type
TMyListBox = class(TMyCustomListBox)
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
如果我要在设计时使用实例TMyListBox
并使用new事件,则在运行时进行测试时,它可以正常工作:
procedure Form1.MyListBox1Addition(Sender: TObject; Index: Integer; Value: string);
begin
ShowMessage('Added Item: [' + Value + '] whose index is: ' + IntToStr(Index));
end;
我如何在TMyListBox
组件源中执行相同的操作,我尝试了一些不同的操作,但没有触发事件或出现错误。
我尝试了什么
1个
type
TMyListBox = class(TMyCustomListBox)
protected
procedure Addition(Sender: TObject; Index: Integer; Value: string);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
constructor TMyListBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
OnAddition := Addition; // shouldn't this call Addition procedure below?
end;
procedure TMyListBox.Addition(Sender: TObject; Index: Integer;
Value: string);
begin
ShowMessage('test'); // doesnt fire
end;
2
与上述相同,仅添加inherited
:
procedure TMyListBox.Addition(Sender: TObject; Index: Integer;
Value: string);
begin
inherited; // no difference
ShowMessage('test'); // doesnt fire
end;
3
我尝试覆盖Addition
方法声明:
procedure Addition(Sender: TObject; Index: Integer; Value: string); override;
Addition
在基类中找不到错误。
4
我什至尝试将声明更改为:
procedure OnAddition(Sender: TObject; Index: Integer; Value: string);
并从构造函数中删除事件处理程序,仍然不会触发。
我也尝试了其他一些方法,但是此时我陷入了死胡同,因此希望朝着正确的方向前进。我确实应该能够解决这个问题,但是我想我一直在解决这个问题上花费太长时间了,而且我的大脑正在融化,所以我等待最有可能成为一个简单明显答案的方法:)
谢谢。
constructor TMyListBox.Create(AOwner: TComponent); begin inherited Create(AOwner); OnAddition := Addition; // shouldn't this call Addition procedure below? end;
这项工作应该很好。不,它不叫 Addition()
,它的地址分配的Addition()
的OnAddition
事件。触发事件后,它将调用 Addition()
。
但是,话虽如此,这是错误的设计。组件永远不要为自己的事件(尤其是published
事件)分配处理程序。正确的解决方案是TMyCustomListBox
声明一个virtual
触发方法,OnAddition
然后在需要时调用该方法。TMyListBox
(或其他任何后代)可以使用override
该方法,inherited
如果希望/当希望触发用户的OnAddition
事件处理程序时,则调用该方法。额外的好处是,即使用户未分配任何事件处理程序,这也允许后代对事件做出反应。
尝试以下方法:
type
TOnAdditionEvent = procedure(Sender: TObject; Index: Integer; Value: string) of object;
TMyCustomListBox = class(TCustomListBox)
private
FOnAddition: TOnAdditionEvent;
protected
procedure DoAddition(Index: Integer; Value: string); virtual;
property OnAddition: TOnAdditionEvent read FOnAddition write FOnAddition;
// ...
end;
procedure TMyCustomListBox.DoAddition(Index: Integer; Value: string);
begin
if Assigned(OnAddition) then
OnAddition(Self, Index, Value);
end;
type
TMyListBox = class(TMyCustomListBox)
protected
procedure DoAddition(Index: Integer; Value: string); override;
// ...
published
property OnAddition;
//...
end;
procedure TMyListBox.DoAddition(Index: Integer; Value: string);
begin
ShowMessage('test'); // doesnt fire
inherited;
end;
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句