Delphi中的事件委派

时间:2017-02-27 10:13:08

标签: c# delphi

当我正在尝试学习一门新语言 Delphi 时,我需要一些帮助。

可能的技术,但不知道如何实施:

以下是Delphi中事件委派的使用:

type
  TMyProcEvent = procedure(const AIdent: string; const AValue: Integer) of object;
  TMyFuncEvent = function(const ANumber: Integer): Integer of object;

在课程中,您可以添加DoEvent(为正确的事件重命名)。所以你可以在内部调用DoEvent。 DoEvent处理未分配事件的可能性。

type
  TMyClass = class
  private
    FMyProcEvent : TMyProcEvent;
    FMyFuncEvent : TMyFuncEvent;
  protected
procedure DoMyProcEvent(const AIdent: string; const AValue: Integer);
function DoMyFuncEvent(const ANumber: Integer): Integer;

  public
    property MyProcEvent: TMyProcEvent read FMyProcEvent write FMyProcEvent;
    property MyFuncEvent: TMyFuncEvent read FMyFuncEvent write FMyFuncEvent;
  end;

procedure TMyClass.DoMyProcEvent(const AIdent: string; const AValue:   Integer);
begin
  if Assigned(FMyProcEvent) then
    FMyProcEvent(AIdent, AValue);
  // Possibly add more general or default code.
end;


function TMyClass.DoMyFuncEvent(const ANumber: Integer): Integer;
begin
  if Assigned(FMyFuncEvent) then
    Result := FMyFuncEvent(ANumber)
  else
    Result := cNotAssignedValue;
end;

Delphi更新

以下是我在 Delphi

中实现的代码

这是我的myclass.pas

unit myclass;

interface

type
  TEvent1 = procedure() of Object;
  TMyClass = class(TComponent)
    private
 FValue: Integer;
 FEvent: TNotifyEvent; // could be TEvent1 aswell
 procedure SetValue(const AValue: Integer);
 function GetValue(): Integer;
  protected
 procedure DoFireEvent();
  public
 constructor Create(AOwner: TComponent); override;
 property Value: Integer read GetValue write SetValue;
  published
 property OnEvent: TNotifyEvent read FEvent write FEvent;
  end;

implementation

procedure TMyClass.SetValue(const AValue: Integer);
begin
  FValue := AValue;
  if AValue < 6 then DoFireEvent();
end;

function TMyClass.GetValue(): Integer;
begin
  Result := FValue;
end;

procedure TMyClass.DoFireEvent();
begin
  if Assigned(FEvent) then FEvent(Self);
end;

constructor TMyClass.Create(AOwner: TComponent); 
begin
  FEvent := nil;
  FValue := 10;
end

end.

以下是form11.pas,它有表单控件:         unit form11;

interface

uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,myclass;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure MyClassEventHandler(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.MyClassEventHandler(Sender: TObject);
begin
  ShowMessage('Value is now below 6: ' + IntToStr(TMyClass(Sender).Value));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  myclass: TMyClass;
begin
  myclass := TMyClass.Create(nil);
  try
    myclass.OnEvent := MyClassEventHandler;
    myclass.Value := 9; // no event
    myclass.Value := 3; // event
    myclass.Value := 8; // no event;

    // show it's current value
    ShowMessage(IntToStr(myclass.Value));
  finally
    myclass.Free();
  end;

end.
  
    

我在myclass.pas中遇到以下错误:

         

[错误] myclass.pas(7):未声明的标识符:&#39; TComponent&#39;

         

[错误] myclass.pas(10):未声明的标识符:&#39; TNotifyEvent&#39;

         

[错误] myclass.pas(16):无法覆盖静态方法

         

[错误] myclass.pas(37):不兼容的类型

         

[错误] myclass.pas(46):&#39;;&#39;预期,但&#39;结束&#39;结果

  

所有学习和谷歌搜索后的最终代码:

unit myclass;

interface

uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

    type
  MyInterfce = procedure (var AValue: Integer; var isbreak: Boolean) of object;

  TMyClass = class
  private
    OnEvent: MyInterfce;
  public
     constructor Create();

     procedure DoFireEvent();
  published

    property MyEvent  :  MyInterfce read OnEvent write OnEvent;
  end;

implementation


procedure TMyClass.DoFireEvent();
var i : integer;
isbreaked: boolean;
begin
  isbreaked:= false;
  for i :=0 to 5 do
  begin
    if assigned (MyEvent) then MyEvent(i,isbreaked);
    Application.ProcessMessages;
    if  isbreaked = true then break;
    Sleep(1000);
  end;
  //ShowMessage(IntToStr(integer(i)));
    //for i :=0 to 20 do
  //FEvent := IntToStr(i);
end;

constructor TMyClass.Create();
begin
;
end;

end.


unit form11;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,myclass;

type
 TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure MyClassEventHandler(var value:Integer; var isbreak: Boolean);
procedure Button2Click(Sender: TObject);
  private
{ Private declarations }
  public
{ Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.MyClassEventHandler(var value:Integer;var isbreak:     Boolean);
begin
    Edit1.Text:=IntToStr(value);

end;

procedure TForm1.Button1Click(Sender: TObject);
var
  myclass: TMyClass;
begin
  myclass := TMyClass.Create();
  try
myclass.MyEvent := MyClassEventHandler;
myclass.DoFireEvent();
  finally
    myclass.Free();
  end;

end;

procedure TForm1.Button2Click(Sender: TObject);
var
  myclass: TMyClass;
begin
  myclass.FreeInstance();
  end;

end.

1 个答案:

答案 0 :(得分:3)

问题实际上与事件委托无关,而且C#代码不相关。你刚刚遇到一些平庸的编译器错误。

让我们阅读错误消息,看看我们是否能理解他们所说的内容。

  

[错误] myclass.pas(7):未声明的标识符:'TComponent'

您引用.bak,但编译器无法识别该标识符。为什么不?因为您没有使用定义它的单位。

您需要将单位添加到TComponent子句,以便编译器可以找到这些符号。查看前两个错误,usesTComponent要求您使用TNotifyEvent。其他错误只是编译器无法使用Classes的后果。

对您的单位进行以下更改:

TComponent