用参数调用eventhandler

Visual Studio 2008,C#3.0。

我在下面有一个调用事件处理程序的方法。 我想将方法​​接收的两个参数传递给事件处理程序。

我想做这样的事情:

wc.DownloadDataCompleted += wc.DownloadedDataCompleted(strtitle, placeid); 

这是否可能,如果是的话,我将如何去做呢?

代码片段:

 public void downloadphoto(string struri,string strtitle,string placeid) { using (WebClient wc = new WebClient()) { wc.DownloadDataCompleted += wc_DownloadDataCompleted; wc.DownloadDataAsync(new Uri(struri)); } } 

最简单的方法是使用匿名函数 (匿名方法或lambda表达式)来订阅事件,然后使您的方法只具有您想要的参数:

 public void downloadphoto(string struri, string strtitle, string placeid) { using (WebClient wc = new WebClient()) { wc.DownloadDataCompleted += (sender, args) => DownloadDataCompleted(strtitle, placeid, args); wc.DownloadDataAsync(new Uri(struri)); } } // Please rename the method to say what it does rather than where it's used :) private void DownloadDataCompleted(string title, string id, DownloadDataCompletedEventArgs args) { // Do stuff here } 

DownloadDataAsync有一个重载,它接受一个对象:

 DownloadDataAsync(uri, object) 

该对象可以是您希望传递给DownloadDataCompleted handler任意内容:

 public void downloadphoto(string struri,string strtitle,string placeid) { using (WebClient wc = new WebClient()) { string[] data = new string[2] { strtitle, placeid }; wc.DownloadDataCompleted += wc_DownloadDataCompleted; wc.DownloadDataAsync(new Uri(struri), data); } } void wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e) { string[] data = (string[])e.UserToken; string strtitle = data[0]; string placeid = data[1]; } 

您可以创建一个私有类并将处理程序放在那里。 例如

  public void downloadphoto(string struri, string strtitle, string placeid) { using (WebClient wc = new WebClient()) { wcHandler handler = new wcHandler() { Strtitle = strtitle, Placeid = placeid }; wc.DownloadDataCompleted += handler.wc_DownloadDataCompleted; wc.DownloadDataAsync(new Uri(struri)); } } private class wcHandler { public string Strtitle { get; set; } public string Placeid { get; set; } public void wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e) { // Do Stuff } } 

虽然,鉴于Jon的答案的优雅可能会使用它!

Jon Skeet已经回答了这个问题,展示了如何使用lamda表达式,但我仍然不清楚它。 我还需要更多的例子,并最终使用按钮找到了这个简单的案例: http : //social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/74d03fe0-0fa5-438d-80e0-cf54fa15af0e

 void A() { Popup parameter = new Popup(); buttonClose.Click += (sender, e) => { buttonClose_Click(sender, e, parameter); }; } static void buttonClose_Click(object sender, EventArgs e, Popup parameter) { MakeSomethingWithPopupParameter(parameter); } 

在我的例子中,我使用了一个TreeView控件的上下文菜单,最终看起来像这样:

 private void TreeViewCreateContextMenu(TreeNode node) { ContextMenuStrip contextMenu = new ContextMenuStrip(); // create the menu items ToolStripMenuItem newMenuItem = new ToolStripMenuItem(); newMenuItem.Text = "New..."; // add the menu items to the menu contextMenu.Items.AddRange(new ToolStripMenuItem[] { newMenuItem }); // add its event handler using a lambda expression, passing // the additional parameter "myData" string myData = "This is the extra parameter."; newMenuItem.Click += (sender, e) => { newMenuItem_Click(sender, e, myData); }; // finally, set the node's context menu node.ContextMenuStrip = contextMenu; } // the custom event handler, with "extraData": private void newMenuItem_Click(object sender, EventArgs e, string extraData) { // do something with "extraData" }