如何使用参数调用 TEvent 的简单示例
Simple example how to Invoke TEvent with params
我正在尝试将 Spring4d 框架用于 Delphi,并且我想使用多播事件。在使用“正常”TNotifyEvent 时,它可以工作并且处理程序将被调用两次。
uses
...
Spring,
Spring.Events,
Spring.Events.Base;
procedure TfrmMain.EventHandler1(Sender: TObject);
begin
Log('called handler1');
end;
procedure TfrmMain.btnNotifyEventClick(Sender: TObject);
var
MulticastEvent: TEvent<TNotifyEvent>;
begin
MulticastEvent := TEvent<TNotifyEvent>.Create;
try
MulticastEvent.Add(EventHandler1);
MulticastEvent.Add(EventHandler1);
MulticastEvent.Add(EventHandler1);
MulticastEvent.Remove(EventHandler1);
MulticastEvent.Invoke;
finally
MulticastEvent.Free;
end;
end;
但我不知道如何将这些多播事件与我自己的事件一起使用 TSyncEvent
。 EventHandler2 需要一个字符串。所以我想用文本调用Invoke方法。
type
TSyncEvent = procedure(Sender: TObject; const iMsg: string) of object;
procedure TfrmMain.EventHandler2(Sender: TObject; const iMsg: string);
begin
Log('called handler2: '+iMsg);
end;
procedure TfrmMain.btnSyncEventClick(Sender: TObject);
var
MulticastEvent: TEvent<TSyncEvent>;
begin
MulticastEvent := TEvent<TSyncEvent>.Create;
try
MulticastEvent.Add(EventHandler2);
MulticastEvent.Add(EventHandler2);
MulticastEvent.Invoke('text for handler2');
finally
MulticastEvent.Free;
end;
end;
此代码未编译并出现错误消息“方法调用的参数过多”。不幸的是,在框架或项目页面上没有使用多播事件的示例。我正在使用 Delphi 10.3.3 社区版。
谢谢。
您不应该使用 Spring.Events.pas
中的 TEvent<T>
class,因为它是一个实现细节,事实上,在 2.0 中它甚至不再存在,因为它被重构了。
相反,使用 Spring.pas
中的记录类型 Event<T>
。它不需要创建或销毁,因为它会自动执行。
在代码中更改它后,您会发现缺少 Sender
参数。
按Ctrl+Shift+Space可以看到Invoke
的参数- 它具有与您提供的 T
类型完全相同的签名。
固定码:
procedure TfrmMain.btnSyncEventClick(Sender: TObject);
var
MulticastEvent: Event<TSyncEvent>;
begin
MulticastEvent.Add(EventHandler2);
MulticastEvent.Add(EventHandler2);
MulticastEvent.Invoke(Sender, 'text for handler2');
end;
我正在尝试将 Spring4d 框架用于 Delphi,并且我想使用多播事件。在使用“正常”TNotifyEvent 时,它可以工作并且处理程序将被调用两次。
uses
...
Spring,
Spring.Events,
Spring.Events.Base;
procedure TfrmMain.EventHandler1(Sender: TObject);
begin
Log('called handler1');
end;
procedure TfrmMain.btnNotifyEventClick(Sender: TObject);
var
MulticastEvent: TEvent<TNotifyEvent>;
begin
MulticastEvent := TEvent<TNotifyEvent>.Create;
try
MulticastEvent.Add(EventHandler1);
MulticastEvent.Add(EventHandler1);
MulticastEvent.Add(EventHandler1);
MulticastEvent.Remove(EventHandler1);
MulticastEvent.Invoke;
finally
MulticastEvent.Free;
end;
end;
但我不知道如何将这些多播事件与我自己的事件一起使用 TSyncEvent
。 EventHandler2 需要一个字符串。所以我想用文本调用Invoke方法。
type
TSyncEvent = procedure(Sender: TObject; const iMsg: string) of object;
procedure TfrmMain.EventHandler2(Sender: TObject; const iMsg: string);
begin
Log('called handler2: '+iMsg);
end;
procedure TfrmMain.btnSyncEventClick(Sender: TObject);
var
MulticastEvent: TEvent<TSyncEvent>;
begin
MulticastEvent := TEvent<TSyncEvent>.Create;
try
MulticastEvent.Add(EventHandler2);
MulticastEvent.Add(EventHandler2);
MulticastEvent.Invoke('text for handler2');
finally
MulticastEvent.Free;
end;
end;
此代码未编译并出现错误消息“方法调用的参数过多”。不幸的是,在框架或项目页面上没有使用多播事件的示例。我正在使用 Delphi 10.3.3 社区版。
谢谢。
您不应该使用 Spring.Events.pas
中的 TEvent<T>
class,因为它是一个实现细节,事实上,在 2.0 中它甚至不再存在,因为它被重构了。
相反,使用 Spring.pas
中的记录类型 Event<T>
。它不需要创建或销毁,因为它会自动执行。
在代码中更改它后,您会发现缺少 Sender
参数。
按Ctrl+Shift+Space可以看到Invoke
的参数- 它具有与您提供的 T
类型完全相同的签名。
固定码:
procedure TfrmMain.btnSyncEventClick(Sender: TObject);
var
MulticastEvent: Event<TSyncEvent>;
begin
MulticastEvent.Add(EventHandler2);
MulticastEvent.Add(EventHandler2);
MulticastEvent.Invoke(Sender, 'text for handler2');
end;