4

我有一段代码,如下所示:

接口部分:

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:已发布的属性属性未显示在对象检查器中。我想我犯了一个错误,在这里忘记了一些东西。

问题 2:如上所示,来自类助手的重写方法没有触发(没有工作)。

问题 3:如上所示的拦截器类中的重写方法没有触发(没有工作)。

任何人都可以帮我找出问题所在吗?感谢您的帮助,并为我糟糕的英语感到抱歉。

4

4 回答 4

8

问题 1

助手中的已发布属性不会显示在对象检查器中。

这是正确的。在助手中声明的属性永远不会出现在对象检查器中。

问题 2

虚拟方法在类助手中无效。

同样,这是设计使然。尽管编译器允许您在帮助程序中定义虚拟方法,但它没有任何作用。为了TCustomEditHelper.OrganizerChanged射击,TCustomEditHelper需要成为目标对象的主动助手。

问题 3

Change我截获的类的方法TEdit没有触发。

那是因为您没有实例化被拦截的TEdit. 如果您实例化正确的类,即您定义的拦截器类,该方法将触发。

于 2012-12-10T18:30:52.733 回答
4

辅助类可以被认为是一个常规的非面向对象的函数,它接受对象作为它的第一个参数。助手让您可以隐藏它并像调用方法一样编写代码。如果您将它们视为简单的函数,那么您就会明白为什么它们不会出现在对象检查器中或使用访问对象内部的任何地方(如虚拟方法表、调度方法和发布的属性),因为没有内部对象的变化。

于 2013-04-23T20:27:45.030 回答
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通过在第一次调用时创建它。关键是自我

于 2021-07-11T11:28:07.870 回答
0

这样的决定不言自明。

TControlHelper = class helper for TControl
private
    function GetTest: Integer;
protected
    property Test: Integer read GetTest;
end;

TMyThing = class(TControl)
published
    property Test;
end;

您将看到 Test in designtime 属性。但是,在编译实际项目时,我们得到 [dcc32 Fatal Error] F2084 Internal Error: AV0A967995(0A8F0000)-R00000000-0

于 2021-07-11T10:35:23.077 回答