Подписаться на событие с отражением - PullRequest
8 голосов
/ 05 ноября 2010

У меня очень простой класс:

class Trace
{
    void WriteTrace()
    {
        Console.WriteLine("Trace !");
    }
}

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

В моем классе Trace у меня есть этот метод:

public void SubscribeEvent (Control control)
{
        if (type.IsAssignableFrom(control.GetType()))
        {
            Trace test = this;
            MethodInfo method = typeof(Trace).GetMethod("WriteTrace");

            // Subscribe to the event
            EventInfo eventInfo = control.GetType().GetEvent("Load"); // We suppose control is a form 
            Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, control, method); // ERROR : Error binding to target method

        }
    }
}

В последней строке есть ошибка: Ошибка привязки к целевому методу. Что не так в моем фрагменте?

Спасибо!

РЕДАКТИРОВАТЬ : ОК, ошибки больше нет, но когда из формы вызывается событие «Load», метод WriteTrace не вызывается (я поставил точку останова, но она не достигнута). Почему?

Извините за редактирование, все работает очень хорошо:)

Ответы [ 2 ]

9 голосов
/ 05 ноября 2010

С некоторыми изменениями я смог выполнить ваш образец.

Во-первых, метод в Trace должен иметь другую подпись, чтобы соответствовать типу EventHandler:

public class Trace
{
    public void WriteTrace(object sender, EventArgs e)
    {
        Console.WriteLine("Trace !");
    }
}

Затем в SubscribeEvent были внесены некоторые изменения:

public void SubscribeEvent(Control control)
{
    if (typeof(Control).IsAssignableFrom(control.GetType()))
    {
        Trace test = this;
        MethodInfo method = typeof(Trace).GetMethod("WriteTrace");

        EventInfo eventInfo = control.GetType().GetEvent("Load");

        // Create the delegate on the test class because that's where the
        // method is. This corresponds with `new EventHandler(test.WriteTrace)`.
        Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, test, method);
        // Assign the eventhandler. This corresponds with `control.Load += ...`.
        eventInfo.AddEventHandler(control, handler);
    }
}

Надеюсь, это поможет.

1 голос
/ 05 ноября 2010

Ваша первая проблема заключается в том, что подпись метода Trace.WriteTrace не соответствует синтаксису обработчика событий Form.Load

Попробуйте это:

void WriteTrace(object sender, EventArgs e)
{
    Console.WriteLine("Trace !");
}

Кроме того, ваш вызов CreateDelegate должен передать объект трассировки, а не объект управления:

Trace test = this;
MethodInfo method = typeof(Trace).GetMethod("WriteTrace");

// Subscribe to the event
EventInfo eventInfo = control.GetType().GetEvent("Load"); // We suppose control is a form 

Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, method); // ERROR : Error binding to target method
eventInfo.AddEventHandler(control, handler);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...