Как динамически подписаться на событие? - PullRequest
2 голосов
/ 22 сентября 2010

СВЯЗАННЫХ


Мне нужно определить, когда происходит событие. Для этого я пытаюсь динамически подписаться на событие.

Проблема в том, что у меня разные типы делегатов, не все события имеют одинаковую подпись. Решения предоставили здесь и здесь ожидает object sender, EventArgs e, который я не использую, поэтому я получаю исключение, сообщающее, что типы не совпадают.

Вот несколько примеров моего делегата:

public delegate void OnEventA(int id);
public delegate void OnEventB(double num, string name);

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

Ответы [ 2 ]

6 голосов
/ 22 сентября 2010

EventInfo имеет метод AddEventHandler, который вы можете использовать.Если у вас нет экземпляра делегата, вы можете динамически создать делегата, используя Delegate.CreateDelegate:

var eh = Delegate.CreateDelegate(ei.EventHandlerType, target, methodInfo);
ei.AddEventHandler(owner, eh);

В этом примере target является целевым объектом для делегата, а methodInfo являетсяMethodInfo метода в target объекте.Наконец, owner - это объект, которому принадлежит событие ei.

2 голосов
/ 23 сентября 2010

После некоторых исследований я нашел несколько статей:

Это помогло мне понять, что я пытался сделать, и я должен сделать.

Мне нужно использовать Delegate.CreateDelegate, передаваяEventHandlerType (тип события, делегат), экземпляр класса и информация о методе метода (из класса в предыдущем параметре), который будет обрабатывать событие.Цель - это элемент управления, который вызывает это событие.

Delegate handler = Delegate.CreateDelegate(evt.EventHandlerType, abc, mi1, false);
evt.AddEventHandler(target, handler);

Дальнейшие раскопки привели меня к этому методу.Я могу подписаться на события, используя лямбда-выражения.Используя Action<T> я могу подписаться на разные типы и числа параметров.

public static Delegate Create<T>(EventInfo e, Action<T> a)
{
    var parameters = e.EventHandlerType.GetMethod("Invoke").GetParameters().Select(p => Expression.Parameter(p.ParameterType, "p")).ToArray();
    var exp = Expression.Call(Expression.Constant(a), a.GetType().GetMethod("Invoke"), parameters);
    var l = Expression.Lambda(exp, parameters);
    return Delegate.CreateDelegate(e.EventHandlerType, l.Compile(), "Invoke", false);
}

Используя этот метод (e - EventInfo; EventManager - класс со статическим методом выше)

e.AddEventHandler(this, EventManager.Create<int>(e, (x) => Console.WriteLine("Execute")));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...