将参数传递给EventHandler

134

我有以下的EventHandler,我添加了一个名为music的参数:

public void PlayMusicEvent(object sender, EventArgs e,MusicNote music)
{
    music.player.Stop();
    System.Timers.Timer myTimer = (System.Timers.Timer)sender;
    myTimer.Stop();
}

我需要像这样将处理程序添加到 Timer

myTimer.Elapsed += new ElapsedEventHandler(PlayMusicEvent(this, e, musicNote));

但是会出现以下错误:

"需要方法名称"

编辑:在这种情况下,我只是从包含此代码片段的方法中传递 e,那么我该如何传递计时器自己的 EventArgs


8
重复问题的答案不好,这里的顶级回答应该成为标准答案。 - John Shedletsky
2个回答

318

Timer.Elapsed 期望具有特定签名(参数为 objectEventArgs)的方法。如果您想在事件注册期间使用带有额外参数的 PlayMusicEvent 方法,您可以使用 lambda 表达式作为适配器:

myTimer.Elapsed += new ElapsedEventHandler((sender, e) => PlayMusicEvent(sender, e, musicNote));

编辑:您还可以使用更短的版本:

myTimer.Elapsed += (sender, e) => PlayMusicEvent(sender, e, musicNote);

1
谢谢,它起作用了!我不得不更改第一组括号中的发送者和e的名称,因为它们与包含方法中的名称相同。您能否向我解释一下它们是什么?即第一个括号中的发送者、e和第二个括号中的有什么区别? - Matt
4
(sender, e) => PlayMusicEvent(sender, e, musicNote) 是一个匿名方法。第一个括号中的值是实际参数名称,第二个括号中的值是实际参数的使用方法。将其视为以下形式的简写:void NONAME(var sender, var e) { PlayMusicEvent(sender, e, musicNote); },其中参数名称从上下文中推断出来,musicNote取自局部变量。这一行代码创建了一个新方法,它使用了你的方法,并将其设置为定时器事件的处理程序。 - MagnatLU
22
如何移除这个 eventHandler-= 不起作用。 - user2742371
2
@EruRōraito http://stackoverflow.com/questions/17995339/detach-event-handler-after-attaching-method-with-passed-parameter?noredirect=1#comment26312041_17995339 - TruthOf42
6
在这种情况下,无法取消订阅匿名方法(如Yassine Houssni所述)。要取消订阅,您需要在某个地方存储事件处理程序对象(ElapsedEventHandler),并从确切的实例中取消订阅。 - white.zaz
显示剩余5条评论

4

如果我理解你的问题正确,你是在调用一个方法而不是将其作为参数传递。请尝试以下操作:

myTimer.Elapsed += PlayMusicEvent;

where

public void PlayMusicEvent(object sender, ElapsedEventArgs e)
{
    music.player.Stop();
    System.Timers.Timer myTimer = (System.Timers.Timer)sender;
    myTimer.Stop();
}

但是你需要考虑存储笔记的位置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接