将参数传递给EventHandler

Mat*_*att 94 c# parameter-passing event-handling

我有以下内容EventHandler,我添加了一个参数MusicNote音乐:

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

我需要将处理程序添加到Timer类似的内容中:

myTimer.Elapsed += new ElapsedEventHandler(PlayMusicEvent(this, e, musicNote));
Run Code Online (Sandbox Code Playgroud)

但得到错误:

"方法名称预期"

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

Mag*_*tLU 242

Timer.Elapsed期望特定签名的方法(带参数objectEventArgs).如果要在事件注册期间使用您的PlayMusicEvent方法和其他参数进行评估,可以使用lambda表达式作为适配器:

myTimer.Elapsed += new ElapsedEventHandler((sender, e) => PlayMusicEvent(sender, e, musicNote));
Run Code Online (Sandbox Code Playgroud)

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

myTimer.Elapsed += (sender, e) => PlayMusicEvent(sender, e, musicNote);
Run Code Online (Sandbox Code Playgroud)

  • 以及如何删除这个`eventHandler`?` - =`不起作用. (11认同)
  • `(sender,e)=> PlayMusicEvent(sender,e,musicNote)`是匿名方法.第一个括号中的值是实际参数名称,第二个括号中的值是实际参数的用法.可以把它想象成`void NONAME(var sender,var e){PlayMusicEvent(sender,e,musicNote); 参数名称是从上下文中推断出来的,而"musicNote"是从局部变量中获取的.这一行创建了一个使用您的方法的新方法,并将其设置为计时器事件的处理程序. (4认同)
  • 在这种情况下,从匿名方法取消订阅(如Yassine Houssni提到的)是不可能的.要取消订阅,您需要在某处存储事件处理程序对象(ElapsedEventHandler)并完全取消订阅该实例. (3认同)
  • @EruRōraito http://stackoverflow.com/questions/17995339/detach-event-handler-after-attaching-method-with-passed-parameter?noredirect=1#comment26312041_17995339 (2认同)

Dmi*_*tsa 5

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

myTimer.Elapsed += PlayMusicEvent;
Run Code Online (Sandbox Code Playgroud)

哪里

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

但是你需要考虑在哪里存储你的笔记.