С# передача дополнительных параметров обработчику событий?
50 Andy Hin [2010-11-18 17:33:00]
Скажем, я хочу передать некоторые дополнительные данные при назначении обработчика событий. Рассмотрим следующий код:
private void setup(string someData)
{
Object.assignHandler(evHandler);
}
public void evHandler(Object sender)
{
// need someData here!!!
}
Как я могу получить некоторые данные в моем методе evHandler?
c# callback events
8 ответов
49 Решение spender [2010-11-18 17:38:00]
private void setup(string someData)
{
Object.assignHandler((sender) => evHandler(sender,someData));
}
public void evHandler(Object sender, string someData)
{
// need someData here!!!
}
17 Marc Gravell [2010-11-18 17:37:00]
Захваченные переменные:
private void setup(string someData)
{
Object.assignHandler((sender,args) => {
evHandler(sender, someData);
});
}
public void evHandler(Object sender, string someData)
{
// use someData here
}
Или (вариант С# 2.0):
Object.assignHandler((EventHandler)delegate(object sender,EventArgs args) {
evHandler(sender, someData);
});
13 delliottg [2016-01-06 01:55:00]
Мне было трудно определить пример @spender выше, особенно с помощью: Object.assignHandler((sender) => evHandler(sender,someData));
, потому что в буквальном смысле нет такой вещи, как Object.assignHandler
. Поэтому я сделал немного больше Google и нашел этот пример. Ответ Питера Дунихо был тем, который щелкнул в моей голове (это не моя работа):
надрез
Обычный подход заключается в использовании анонимного метода с обработчиком событий который имеет вашу измененную подпись. Например:
void Onbutton_click(object sender, EventArgs e, int i) { ... } button.Click += delegate(object sender, EventArgs e) { Onbutton_click(sender, e, 172); };
Конечно, вам не нужно проходить в 172 или даже делать третий параметр int.:)
/надрез
Используя этот пример, я смог передать два пользовательских объекта ComboBoxItem
в событие Timer.Elapsed
с использованием лямбда-нотации:
simulatorTimer.Elapsed +=
(sender, e) => onTimedEvent(sender, e,
(ComboBoxItem) cbPressureSetting.SelectedItem,
(ComboBoxItem) cbTemperatureSetting.SelectedItem);
а затем в него обработчик:
static void onTimedEvent(object sender, EventArgs e, ComboBoxItem pressure, ComboBoxItem temperature)
{
Console.WriteLine("Requested pressure: {0} PSIA\nRequested temperature: {1}° C", pressure, temperature);
}
Это не новый код из приведенных выше примеров, но он демонстрирует, как их интерпретировать. Надеюсь, кто-то вроде меня найдет его поучительным и полезным, поэтому они не проводят часы, пытаясь понять концепцию, как я.
Этот код работает в моем проекте (за исключением исключений, не связанных с потоком, с объектами ComboBoxItem
, которые, как я полагаю, не изменяет способ работы примера). Теперь я это выясню.
2 Idan [2013-12-18 20:41:00]
вы можете попробовать:
string yourObject;
theClassWithTheEvent.myEvent += (sender, model) =>
{
yourObject = "somthing";
}
0 Ramius [2016-08-03 08:57:00]
Вот мое однострочное решение, которое передает дополнительные параметры обработчику таймера.
private void OnFailed(uint errorCode, string message)
{
ThreadPoolTimer.CreateTimer((timer) => {
UI.ErrorMessage = string.Format("Error: 0x{0:X} {1}", errorCode, message);
}, System.TimeSpan.FromMilliseconds(100));
}
0 user441521 [2017-03-03 00:20:00]
Мой вопрос, который был похож, был отмечен дубликатом, поэтому я подумал, что добавлю здесь ответ, так как он не позволит мне ответить на мой вопрос.
class Program
{
delegate void ComponentEventHandler(params dynamic[] args);
event ComponentEventHandler onTest;
static void Main(string[] args)
{
Program prg = new Program();
// can be bound to event and called that way
prg.onTest += prg.Test;
prg.onTest.Invoke("What", 5, 12.0);
Console.ReadKey();
}
public void Test(params dynamic[] values)
{
// assign our params to variables
string name = values[0];
int age = values[1];
double value = values[2];
Console.WriteLine(name);
Console.WriteLine(age);
Console.WriteLine(value);
}
}
0 CodingGorilla [2010-11-18 17:37:00]
Ну, простейший идентификатор метода, чтобы сделать someData
переменную-член так:
public class MyClass
{
private string _eventData;
private void setup(string someData)
{
_eventData = someData;
Object.assignHandler(evHandler);
}
public void evHandler()
{
// do something with _eventData here
}
}
Я не уверен, что это лучший способ сделать это, но это действительно зависит от типа события, объекта и т.д.
0 Michael Geier [2015-02-21 13:53:00]
Вы можете создать пользовательский объект, имеющий дополнительные свойства на основе Object:
class CustomObject : Object
{
public string SomeData;
}
private void setup(string someData)
{
CustomObject customObject = new CustomObject { SomeData = someData };
CustomObject.assignHandler(evHandler);
}
public void evHandler(Object sender)
{
string someData = ((CustomObject)sender).SomeData;
}
Если после инициализации данные больше не должны меняться, вы также можете добавить пользовательский конструктор.