2009-09-28 75 views
11

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)); 
    } 
} 

回答

25

做到這一點,最簡單的方法是使用匿名函數(匿名方法或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 
} 
+1

太棒了!現在誰會有這個! – dezkev 2009-09-29 09:55:50

+3

你如何取消訂閱活動? – jdelator 2012-04-05 01:36:46

+2

@jdelator:您需要將代理存儲在變量中並使用它來取消訂閱。 – 2012-04-05 05:50:32

4

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]; 
} 
+0

Jon的版本很時髦,但是這個工程並且與非3.5的東西兼容。 – womp 2009-09-28 16:59:00

+0

@womp喬恩的版本是時髦真棒,但這個作品,並與非3.5的東西兼容:) – 2009-09-28 17:01:00

+0

所以我們同意。這真是太棒了。 – womp 2009-09-28 17:10:52

2

您可以創建一個私有類,並將處理程序在那裏。例如。

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的答案的優雅可能會使用它!

1

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" 
} 
相關問題