2009-09-28 35 views
11

Visual Studio 2008, C# 3.0.gọi một eventhandler với các đối số

Tôi có một phương thức dưới đây gọi một trình xử lý sự kiện. Tôi muốn chuyển hai đối số nhận được bởi phương thức cho trình xử lý sự kiện.

Tôi muốn làm điều gì đó như thế này:

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

Đây có phải là thậm chí có thể, nếu có, làm thế nào tôi sẽ đi về làm việc đó?

Đoạn Mã:

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

Trả lời

25

Cách đơn giản nhất để làm điều này là sử dụng một anonymous function (một phương pháp ẩn danh hoặc một biểu thức lambda) để đăng ký sự kiện này, sau đó đưa ra phương pháp của bạn có chỉ là thông số bạn muốn:

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

Tuyệt vời !! bây giờ ai có thể thunk !! – dezkev

+3

Bạn làm cách nào để hủy đăng ký sự kiện? – jdelator

+2

@jdelator: Bạn sẽ cần phải lưu trữ các đại biểu trong một biến và sử dụng để bỏ đăng ký. –

4

DownloadDataAsync có quá tải mà phải mất một đối tượng:

DownloadDataAsync(uri, object) 

đối tượng đó có thể là bất cứ điều tùy ý bạn muốn điều đó được thông qua vào 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

Phiên bản của Jon rất sôi nổi, nhưng nó hoạt động và tương thích với những thứ không phải là 3.5. – womp

+0

@womp Phiên bản của Jon là funky tuyệt vời, nhưng tính năng này hoạt động và tương thích với các nội dung không phải là 3,5 :) –

+0

Vì vậy, chúng tôi đồng ý. Thật tuyệt vời. – womp

2

Bạn có thể tạo ra một lớp riêng và đặt xử lý trong đó. Ví dụ.

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

Mặc dù, do sự thanh lịch của câu trả lời của Jon, có lẽ sẽ sử dụng điều đó!

1

Jon Skeet đã trả lời câu hỏi này, cho thấy cách sử dụng biểu thức lamda, nhưng tôi vẫn chưa rõ về nó. Tôi vẫn cần một số ví dụ khác, và cuối cùng tìm thấy trường hợp này đơn giản bằng cách sử dụng nút: 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); 
} 


Trong trường hợp của tôi, tôi đã sử dụng một menu ngữ cảnh cho một điều khiển TreeView, mà kết thúc lên trông như này:

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" 
} 
Các vấn đề liên quan