我有一段代码如下所示:
接口部分:
TControlOrganizer = class(TComponent) // a kind of List of TControl
private
FList : TList; //Handling list of TControl
..............
end;
TControlHelperAdd = class // Just for separating value entered by user and value produced by code
private
FOrganizer : TControlOrganizer;
FOrigValue : String;
FUserValue : String;
end;
TControlHelper = class helper for TControl //Basic helper for TControl
private
class var
FAddProp : TControlHelperAdd;
protected
procedure SetOrganizer(Value : TControlOrganizer);
function getOrganizer:TControlOrganizer;
public
class Constructor doinit;
class Destructor deinit;
procedure OrganizerChanged;virtual;
published
Property Organizer:TControlOrganizer read getOrganizer write setOrganizer; //Problem No.1
end;
//Helper for CustomEdit inherited from TControlHelper
TCustomEditHelper = class helper(TControlHelper) for TCustomEdit
protected
procedure OrganizerChanged;override;
end;
//TEdit : interceptor
TEdit= class(StdCtrls.TEdit)
protected
procedure Change;override; //problem No.3
end;
实施部分:
{TControlHelper}
class Constructor TControlHelper.doinit;
begin
FAddProp :=TControlHelperAdd.Create;
end;
class Destructor TControlHelper.deinit;
begin
FreeAndNil(FAddProp);
end;
procedure TControlHelper.OrganizerChanged;
begin
end;
procedure TControlHelper.SetOrganizer(Value : TControlOrganizer);
begin
if FAddProp.FOrganizer<>value then begin
if assigned(FAddProp.FOrganizer) then begin
FAddProp.FOrganizer.remove(self);
end;
FAddProp.FOrganizer:=value;
if assigned(FAddProp.FOrganizer) then begin
FAddProp.FOrganizer.Add(self);
end;
OrganizerChanged; //Problem No.2
end;
end;
function TControlHelper.getOrganizer:TControlOrganizer;
begin
result:=FAddProp.FOrganizer;
end;
{TCustomEditHelper}
procedure TCustomEditHelper.OrganizerChanged; //problem No.2
begin
if assigned(FAddProp) then begin
if assigned(Organizer) then begin
FAddProp.FOrigValue:=Text;
FAddProp.FUserValue:=Text;
end;
end;
end;
{TEdit = Interceptor}
procedure TEdit.Change; //Problem No.3
begin
inherited Change;
FAddProp.FUserValue:=Text;
end;
我发现了3个我自己无法解决的问题。
问题1: 已发布的属性属性未显示在Object Inspector中。我想我犯了一个错误并在这里忘记了一些事情。
问题2: 如上所示,来自类助手的重写方法没有触发(不起作用)。
问题3: 如上所示,来自拦截器类的重写方法没有触发(不起作用)。有人可以帮我找出问题吗? 感谢您的帮助,抱歉我的英语不好。
答案 0 :(得分:8)
问题1
帮助程序中的已发布属性未显示在Object Inspector中。
没错。在助手中声明的属性永远不会出现在对象检查器中。
问题2
虚拟方法对类帮助程序没有影响。
再次,这是设计的。虽然编译器允许您在帮助程序中定义虚方法,但它没有任何效果。为了TCustomEditHelper.OrganizerChanged
触发,TCustomEditHelper
需要成为目标对象的主动帮助者。
问题3
我拦截的
Change
课程的TEdit
方法无法触发。
那是因为你没有实例化截获的TEdit
。如果您实例化了正确的类,您定义的拦截器类,该方法将触发。
答案 1 :(得分:3)
辅助类可以被认为是一个常规的非面向对象的函数,它接受该对象作为它的第一个参数。帮助程序允许您隐藏此代码和代码,就像调用方法一样。如果您将它们视为简单函数,那么您可以看到它们没有出现在对象检查器中或者使用对象内部的任何地方(如虚拟方法表,调度方法和已发布属性)的原因,因为没有内部函数改变了对象。
答案 2 :(得分:0)
这样的决定不言而喻。
TControlHelper = class helper for TControl
private
function GetTest: Integer;
protected
property Test: Integer read GetTest;
end;
TMyThing = class(TControl)
published
property Test;
end;
您将在设计时属性中看到测试。 然而,当编译一个真正的项目时,我们得到 [dcc32 Fatal Error] F2084 内部错误:AV0A967995(0A8F0000)-R00000000-0
答案 3 :(得分:0)
不过,我找到了解决方案。
TControlHelper = class helper for TControl
protected
function GetTest: Integer;
end;
TMyThing = class (TControl)
published
property Test: Integer read GetTest;
end;
这里的Integer类型是有条件的,可能就是你需要的类,
例如,TControlHelper
将切入您的实例,
Spring.Services.ServiceLocator
通过在第一次调用时创建它。关键是 Self