问题描述
由于Delphi中出现匿名方法,我想在VCL组件事件中使用它们。显然,为了向后兼容,VCL没有更新,所以我设法简单的实现一些注意事项。
Since anonymous methods appeared in Delphi I wanted to use them in VCL components events. Obviously for backward compatibility the VCL wasn't updated, so I managed to make a simple implementation with a few caveats.
type
TNotifyEventDispatcher = class(TComponent)
protected
FClosure: TProc<TObject>;
procedure OnNotifyEvent(Sender: TObject);
public
class function Create(Owner: TComponent; Closure: TProc<TObject>): TNotifyEvent; overload;
function Attach(Closure: TProc<TObject>): TNotifyEvent;
end;
implementation
class function TNotifyEventDispatcher.Create(Owner: TComponent; Closure: TProc<TObject>): TNotifyEvent;
begin
Result := TNotifyEventDispatcher.Create(Owner).Attach(Closure)
end;
function TNotifyEventDispatcher.Attach(Closure: TProc<TObject>): TNotifyEvent;
begin
FClosure := Closure;
Result := Self.OnNotifyEvent
end;
procedure TNotifyEventDispatcher.OnNotifyEvent(Sender: TObject);
begin
if Assigned(FClosure) then
FClosure(Sender)
end;
end.
这是如何使用的,例如:
And this is how it's used for example:
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.OnClick := TNotifyEventDispatcher.Create(Self,
procedure (Sender: TObject)
begin
Self.Caption := 'DONE!'
end)
end;
很简单我相信有两个缺点:
Very simple I believe, there are two drawbacks:
-
我必须创建一个组件来管理匿名方法的生命周期(我浪费了更多的内存,这对间接性有点慢,但我更喜欢更多在我的应用程序中清除代码)
I have to create a component to manage the lifetime of the anonymous method (I waste a bit more of memory, and it's a bit slower for the indirection, still I prefer more clear code in my applications)
我必须为每个事件签名实现一个新类(非常简单)。这个有点复杂,但VCL仍然有非常常见的事件签名,对于每一个特殊情况,我创建了这个类,它永远都是这样。
I have to implement a new class (very simple) for every event signature. This one is a bit more complicated, still the VCL has very common event signatures, and for every special case when I create the class it's done forever.
你对这个实现有什么看法?有什么可以让它更好?
What do you think of this implementation? Something to make it better?
推荐答案
你可以看看我的。
然后你可以编写这样的代码:
Then you can write code like this:
function NotifyEvent(Owner: TComponent; Delegates: array of TProc<TObject>): TNotifyEvent; overload;
begin
Result := TEventHandler<TNotifyEvent>.Create<TProc<TObject>>(Owner, Delegates).Invoke;
end;
function NotifyEvent(Owner: TComponent; Delegate: TProc<TObject>): TNotifyEvent; overload;
begin
Result := NotifyEvent(Owner, [Delegate]);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.OnClick := NotifyEvent(Button1, [
procedure(Sender: TObject)
begin
Caption := 'Started';
end,
procedure(Sender: TObject)
begin
if MessageDlg('Continue?', mtConfirmation, mbYesNo, 0) <> mrYes then
begin
Caption := 'Canceled';
Abort;
end;
end,
procedure(Sender: TObject)
begin
Caption := 'Finished';
end]);
end;
这篇关于使用匿名方法的VCL事件 - 您对此实现有什么看法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!