12

Visual Studio 2008、C# 3.0。

以下に、イベント ハンドラーを呼び出すメソッドがあります。メソッドが受け取った 2 つの引数をイベント ハンドラーに渡したいと思います。

私はこのようなことをしたいと思います:

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

4 に答える 4

25

これを行う最も簡単な方法は、無名関数(無名メソッドまたはラムダ式)を使用してイベントをサブスクライブし、メソッドに必要なパラメーターだけを持たせることです。

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
}
于 2009-09-28T16:54:07.657 に答える
5

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];
}
于 2009-09-28T16:54:28.920 に答える
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
        }
    }

しかし、ジョンの答えの優雅さを考えると、おそらくそれを使用するでしょう!

于 2009-09-28T16:55:31.697 に答える
1

Jon Skeet はすでにこれに回答しており、ラムダ式の使用方法を示していますが、私はまだそれについて不明でした。まだいくつかの例が必要でしたが、最終的にボタンを使用したこの単純なケースを見つけました:

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"
}
于 2012-12-27T22:19:04.197 に答える