Я знаю о 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);
}
}
Я думаю, что ваш код не работает, потому что 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);