2010-11-18 5 views
50

Скажем, я хочу передать некоторые дополнительные данные при назначении обработчика событий. Рассмотрим следующий код:C# передача дополнительных параметров обработчику событий?

private void setup(string someData) 
{ 
    Object.assignHandler(evHandler); 
} 

public void evHandler(Object sender) 
{ 
    // need someData here!!! 
} 

Как я могу получить некоторые данные в свой метод evHandler?

+0

У меня есть более стандартное решение в этом вопросе, первый ответ http://stackoverflow.com/questions/14058412/passing-parameter-to-an-event-handler/14058441#14058441 –

ответ

49
private void setup(string someData) 
{ 
    Object.assignHandler((sender) => evHandler(sender,someData)); 
} 
public void evHandler(Object sender, string someData) 
{ 
    // need someData here!!! 
} 
+1

Это отличное решение, но что, если EventHandler уже имеет TArg. Например: + = новый EventHandler (evHandler)? – Roast

+0

Привет @ Лили, не совсем понятно, что вы просите. Возможно, лучше поставить вопрос (а не комментарий) немного более подробно и некоторый код, чтобы продемонстрировать, что вы пытаетесь сделать. – spender

+1

Спасибо, это решило проблему, с которой я столкнулся, но я новичок в C#, так что не могли бы вы объяснить, что это за конструкция языка, или дать мне ключевое слово для google для объяснения? –

0

Ну, самый простой способ идентификатор сделать 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 
    } 
} 

Я не уверен, что это лучший способ сделать это, но это действительно зависит от типа события, объект и т.д.

+1

думал об этом метод, однако установка может быть вызвана несколько раз с различными someData. Эти данные должны быть уникальными для каждого обработчика. –

+0

В этом случае, spender или решение Marc намного лучше – CodingGorilla

17

Захваченные переменные:

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

захвачено переменной === закрытие? – Matt

+2

@Matt - да, захваченные переменные - лексические замыкания. –

+0

Чтобы уточнить, является ли первое решение недействительным для C# .NET 2.0? –

2

вы можете попробовать сделать это:

string yourObject; 

theClassWithTheEvent.myEvent += (sender, model) => 
{ 
yourObject = "somthing"; 
} 
0

Вы можете создать пользовательский объект, имеющий дополнительные свойства на основе объекта:

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

Если данные не должны быть изменены больше После инициализации вы также можете добавить пользовательский конструктор.

14

Мне нелегко было выяснить пример @ spender выше, особенно с: Object.assignHandler((sender) => evHandler(sender,someData));, потому что в буквальном смысле нет такой вещи, как Object.assignHandler. Поэтому я сделал немного больше Google и нашел this example. Ответ Питер Duniho был один, что щелкнуло в голове (это не моя работа):

надрез

Обычный подход заключается в использовании анонимного метода с обработчиком событий, который имеет ваш модифицированный подпись. Например:

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

Это не новый код из приведенных выше примеров, но он демонстрирует h чтобы их интерпретировать. Надеюсь, кто-то вроде меня найдет поучительным &, чтобы они не часами пытались понять концепцию, как я.

Этот код работает в моем проекте (за исключением исключений, не связанных с потоком, с объектами ComboBoxItem, которые, как я считаю, не изменят, как работает этот пример). Теперь я это выясню.

0

Вот мое однострочное решение, которое передает дополнительные параметры обработчику таймера.

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

Мой вопрос, который был похож был отмечен дубликат так, что я хотел бы добавить здесь ответ, так как он не будет препятствовать мне на мой вопрос.

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); 
     } 
    } 
Смежные вопросы