вызов 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));
}
}
4 ответов
самый простой способ сделать это-использовать анонимная функция (анонимный метод или лямбда-выражение), чтобы подписаться на событие, а затем сделать ваш способ только параметры, которые вы хотите:
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
}
}
хотя, учитывая элегантность ответа Джона, вероятно, использовал бы это!
Джон Скит уже ответил на это, показывая, как использовать выражение 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"
}