Как присоединить обработчик событий к событию с помощью отражения?

Я знаю о EventInfo.AddEventHandler(...) метод, который может использоваться для присоединения обработчика к событию. Но что должно быть сделано, если я даже не могу определить надлежащую подпись обработчика событий, как в, у меня даже нет ссылки на событие args ожидаемой обработчиком?

Я объясню проблему с надлежащим кодом.

//Сценарий, когда я имею все в наличии в своем решении, Нулевом Отражательном Сценарии.

internal class SendCommentsManager
{
    public void Customize(IRFQWindowManager rfqWindowManager)
    {
        rfqWindowManager.SendComment += HandleRfqSendComment;
    }

    private void HandleRfqSendComment(object sender, SendCommentEventArgs args)
    {
        args.Cancel = true;
    }
}

Теперь, я хочу достигнуть той же цели при помощи отражения. Я смог выяснить большую часть из него, но когда я присоединяю делегата в событии (использование AddEventHandler) это бросает "Error binding to target method." исключение.

Я понимаю причину позади этого исключения, присоединяя неправильного делегата в событии. Но должен быть некоторый способ достигнуть этого.

 internal class SendCommentsManagerUsingReflection
 {
     public void Customize(IRFQWindowManager rfqWindowManager)
     {
         EventInfo eventInfo = rfqWindowManager.GetType().GetEvent("SendComment");
         eventInfo.AddEventHandler(rfqWindowManager, 
             Delegate.CreateDelegate(eventInfo.EventHandlerType, this, "HandleRfqSendComment"));
         //<<<<<<<<<<ABOVE LINE IS WHERE I AM GOING WRONG>>>>>>>>>>>>>>
     }

     private void HandleRfqSendComment(object sender, object args)
     {
         Type sendCommentArgsType = args.GetType();
         PropertyInfo cancelProperty = sendCommentArgsType.GetProperty("Cancel");
         cancelProperty.SetValue(args, true, null);
     }
 }
8
задан olydis 5 September 2015 в 14:33
поделиться

1 ответ

Я думаю, что ваш код не работает, потому что HandleRfqSendComment является приватным. Вместо этого вы могли бы напрямую создать делегат этого метода, не передавая его имя в CreateDelegate. Затем вам нужно будет преобразовать делегат к нужному типу, используя следующий метод :

public static Delegate ConvertDelegate(Delegate originalDelegate, Type targetDelegateType)
{
    return Delegate.CreateDelegate(
        targetDelegateType,
        originalDelegate.Target,
        originalDelegate.Method);
}

В вашем коде вы можете использовать этот метод следующим образом:

EventInfo eventInfo = rfqWindowManager.GetType().GetEvent("SendComment");
Action<object, object> handler = HandleRfqSendComment;
Delegate convertedHandler = ConvertDelegate(handler, eventInfo.EventHandlerType);
eventInfo.AddEventHandler(rfqWindowManager, convertedHandler);
12
ответ дан 5 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: