代码之家  ›  专栏  ›  技术社区  ›  Manish Basantani

如何使用反射将事件处理程序附加到事件?

  •  7
  • Manish Basantani  · 技术社区  · 16 年前

    EventInfo.AddEventHandler(...)

    //场景当我的解决方案中有所有可用的东西时,零反射场景。

    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);
         }
     }
    
    1 回复  |  直到 10 年前
        1
  •  12
  •   Thomas Levesque    16 年前

    我认为你的代码失败是因为 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);