Event handling and reflection - C# (NetCF)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Klaudiusz Bryja

    Event handling and reflection - C# (NetCF)

    Hi,

    This is for NetCF 2.0.

    I need to create event handling code which using reflection. I have
    some parameters in XML which describe how event should be handled. I
    have code to create delegate:

    public class DelegateEx
    {
    private object target;
    private MethodInfo method;
    private XmlNode node;

    // XmlNode describe how to handle event (dll path, class, method and
    method parameters).
    private DelegateEx(Meth odInfo method, object target, XmlNode
    node)
    {
    this.target = target;
    this.method = method;
    this.node = node;
    }

    // This is called when event was fired.
    // XMLFormsEventAr gs inherits from EventsArgs and add XmlNode
    property.
    private void Invoke(object sender, EventArgs e)
    {
    method.Invoke(t arget, new object[] { sender, (new
    XMLFormsEventAr gs(this.node, e) as EventArgs) });
    }

    public static EventHandler CreateDelegate( MethodInfo method,
    object target, XmlNode node)
    {
    return new EventHandler((n ew DelegateEx(meth od, target,
    node)).Invoke);
    }
    }

    Using this I try to subscribe to event (I have static method
    HandleEvents which should be called when event is fired):

    EventInfo ei = form.GetType(). GetEvent("Click ",
    BindingFlags.Ig noreCase | BindingFlags.Pu blic | BindingFlags.No nPublic
    | BindingFlags.In stance | BindingFlags.St atic);
    if (ei != null)
    {
    MethodInfo miHandler = typeof(XMLForms ).GetMethod("Ha ndleEvents",
    BindingFlags.Ig noreCase | BindingFlags.Pu blic | BindingFlags.No nPublic
    | BindingFlags.In stance | BindingFlags.St atic);

    MethodInfo addHandler = ei.GetAddMethod ();

    // formNode - this is xmlNode which describe event

    Object[] addHandlerArgs = { DelegateEx.Crea teDelegate(miHa ndler,
    typeof(XMLForms ), formNode) };
    addHandler.Invo ke(form, addHandlerArgs) ;
    }

    Everything work when I want to handle standard event which is type of
    EventHandler. But I get error "ArgumentExcept ion" without any message
    when I try to handle e.g. KeyDown event (event is type of
    KeyEventHandler ).

    StackTrace for this error:
    at System.Reflecti on.RuntimeMetho dInfo.InternalI nvoke()
    at System.Reflecti on.RuntimeMetho dInfo.InternalI nvoke()
    at System.Reflecti on.RuntimeMetho dInfo.Invoke()
    at System.Reflecti on.MethodBase.I nvoke()
    at bcs.XMLForms.Bu ildXMLForm()
    at TestApp.Form1.b utton2_Click()
    at System.Windows. Forms.Control.O nClick()
    at System.Windows. Forms.Button.On Click()
    at System.Windows. Forms.ButtonBas e.WnProc()
    at System.Windows. Forms.Control._ InternalWnProc( )
    at Microsoft.AGL.F orms.EVL.EnterM ainLoop()
    at System.Windows. Forms.Applicati on.Run()
    at TestApp.Program .Main()

    I think that I should cast EventHandler type to KeyEventHandler type
    but I get error:
    Cannot convert type 'System.EventHa ndler' to
    'System.Windows .Forms.KeyEvent Handler'.

    How to change my code to work with all type of EventHandler?


    Best regards,
    Klaudiusz
  • Pavel Minaev

    #2
    Re: Event handling and reflection - C# (NetCF)

    On Jul 23, 12:28 pm, Klaudiusz Bryja <bryja_klaudi.. .@poczta.fm>
    wrote:
    Hi,
    >
    This is for NetCF 2.0.
    >
    I need to create event handling code which using reflection. I have
    some parameters in XML which describe how event should be handled. I
    have code to create delegate:
    >
    public class DelegateEx
        {
            private object target;
            private MethodInfo method;
            private XmlNode node;
    >
    // XmlNode describe how to handle event (dll path, class, method and
    method parameters).
            private DelegateEx(Meth odInfo method, object target, XmlNode
    node)
            {
                this.target = target;
                this.method = method;
                this.node = node;
            }
    >
    // This is called when event was fired.
    // XMLFormsEventAr gs inherits from EventsArgs and add XmlNode
    property.
            private void Invoke(object sender, EventArgs e)
            {
                method.Invoke(t arget, new object[] { sender, (new
    XMLFormsEventAr gs(this.node, e) as EventArgs) });
            }
    >
            public static EventHandler CreateDelegate( MethodInfo method,
    object target, XmlNode node)
            {
                return new EventHandler((n ew DelegateEx(meth od, target,
    node)).Invoke);
            }
        }
    >
    Using this I try to subscribe to event (I have static method
    HandleEvents which should be called when event is fired):
    >
    EventInfo ei = form.GetType(). GetEvent("Click ",
    BindingFlags.Ig noreCase | BindingFlags.Pu blic | BindingFlags.No nPublic
    | BindingFlags.In stance | BindingFlags.St atic);
    if (ei != null)
    {
        MethodInfo miHandler = typeof(XMLForms ).GetMethod("Ha ndleEvents",
    BindingFlags.Ig noreCase | BindingFlags.Pu blic | BindingFlags.No nPublic
    | BindingFlags.In stance | BindingFlags.St atic);
    >
        MethodInfo addHandler = ei.GetAddMethod ();
    >
    // formNode - this is xmlNode which describe event
    >
        Object[] addHandlerArgs = { DelegateEx.Crea teDelegate(miHa ndler,
    typeof(XMLForms ), formNode) };
        addHandler.Invo ke(form, addHandlerArgs) ;
    >
    }
    >
    Everything work when I want to handle standard event which is type of
    EventHandler. But I get error "ArgumentExcept ion" without any message
    when I try to handle e.g. KeyDown event (event is type of
    KeyEventHandler ).
    >
    StackTrace for this error:
    at System.Reflecti on.RuntimeMetho dInfo.InternalI nvoke()
    at System.Reflecti on.RuntimeMetho dInfo.InternalI nvoke()
    at System.Reflecti on.RuntimeMetho dInfo.Invoke()
    at System.Reflecti on.MethodBase.I nvoke()
    at bcs.XMLForms.Bu ildXMLForm()
    at TestApp.Form1.b utton2_Click()
    at System.Windows. Forms.Control.O nClick()
    at System.Windows. Forms.Button.On Click()
    at System.Windows. Forms.ButtonBas e.WnProc()
    at System.Windows. Forms.Control._ InternalWnProc( )
    at Microsoft.AGL.F orms.EVL.EnterM ainLoop()
    at System.Windows. Forms.Applicati on.Run()
    at TestApp.Program .Main()
    >
    I think that I should cast EventHandler type to KeyEventHandler type
    but I get error:
    Cannot convert type 'System.EventHa ndler' to
    'System.Windows .Forms.KeyEvent Handler'.
    >
    How to change my code to work with all type of EventHandler?
    Your code passes your own class XMLFormsEventAr gs to a method which
    expects KeyEventArgs. These types are obviously not compatible. Can
    you explain more about what that class is and why is it needed?

    Comment

    • Klaudiusz Bryja

      #3
      Re: Event handling and reflection - C# (NetCF)

      On 23 Lip, 11:32, Pavel Minaev <int...@gmail.c omwrote:
      On Jul 23, 12:28 pm, Klaudiusz Bryja <bryja_klaudi.. .@poczta.fm>
      wrote:
      >
      >
      >
      Hi,
      >
      This is for NetCF 2.0.
      >
      I need to create event handling code which using reflection. I have
      some parameters in XML which describe how event should be handled. I
      have code to create delegate:
      >
      public class DelegateEx
      {
      private object target;
      private MethodInfo method;
      private XmlNode node;
      >
      // XmlNode describe how to handle event (dll path, class, method and
      method parameters).
      private DelegateEx(Meth odInfo method, object target, XmlNode
      node)
      {
      this.target = target;
      this.method = method;
      this.node = node;
      }
      >
      // This is called when event was fired.
      // XMLFormsEventAr gs inherits from EventsArgs and add XmlNode
      property.
      private void Invoke(object sender, EventArgs e)
      {
      method.Invoke(t arget, new object[] { sender, (new
      XMLFormsEventAr gs(this.node, e) as EventArgs) });
      }
      >
      public static EventHandler CreateDelegate( MethodInfo method,
      object target, XmlNode node)
      {
      return new EventHandler((n ew DelegateEx(meth od, target,
      node)).Invoke);
      }
      }
      >
      Using this I try to subscribe to event (I have static method
      HandleEvents which should be called when event is fired):
      >
      EventInfo ei = form.GetType(). GetEvent("Click ",
      BindingFlags.Ig noreCase | BindingFlags.Pu blic | BindingFlags.No nPublic
      | BindingFlags.In stance | BindingFlags.St atic);
      if (ei != null)
      {
      MethodInfo miHandler = typeof(XMLForms ).GetMethod("Ha ndleEvents",
      BindingFlags.Ig noreCase | BindingFlags.Pu blic | BindingFlags.No nPublic
      | BindingFlags.In stance | BindingFlags.St atic);
      >
      MethodInfo addHandler = ei.GetAddMethod ();
      >
      // formNode - this is xmlNode which describe event
      >
      Object[] addHandlerArgs = { DelegateEx.Crea teDelegate(miHa ndler,
      typeof(XMLForms ), formNode) };
      addHandler.Invo ke(form, addHandlerArgs) ;
      >
      }
      >
      Everything work when I want to handle standard event which is type of
      EventHandler. But I get error "ArgumentExcept ion" without any message
      when I try to handle e.g. KeyDown event (event is type of
      KeyEventHandler ).
      >
      StackTrace for this error:
      at System.Reflecti on.RuntimeMetho dInfo.InternalI nvoke()
      at System.Reflecti on.RuntimeMetho dInfo.InternalI nvoke()
      at System.Reflecti on.RuntimeMetho dInfo.Invoke()
      at System.Reflecti on.MethodBase.I nvoke()
      at bcs.XMLForms.Bu ildXMLForm()
      at TestApp.Form1.b utton2_Click()
      at System.Windows. Forms.Control.O nClick()
      at System.Windows. Forms.Button.On Click()
      at System.Windows. Forms.ButtonBas e.WnProc()
      at System.Windows. Forms.Control._ InternalWnProc( )
      at Microsoft.AGL.F orms.EVL.EnterM ainLoop()
      at System.Windows. Forms.Applicati on.Run()
      at TestApp.Program .Main()
      >
      I think that I should cast EventHandler type to KeyEventHandler type
      but I get error:
      Cannot convert type 'System.EventHa ndler' to
      'System.Windows .Forms.KeyEvent Handler'.
      >
      How to change my code to work with all type of EventHandler?
      >
      Your code passes your own class XMLFormsEventAr gs to a method which
      expects KeyEventArgs. These types are obviously not compatible. Can
      you explain more about what that class is and why is it needed?
      XMLFormsEventAr gs inherits from EventArgs and has property:
      XmlNode - this node describie target method which shoudl be called
      after event occured (e.g. in xml I define that when Click occured in
      e.g. button system should call method named "A" from \program files
      \dlls\methoddll .dll from class dllsMethod),

      OK. I try to explain what I want to do. I have XML file which describe
      control leyout and how events should be handled.

      <System.Windows .Forms.Button Name="btnEnter" Text="Button text" >
      <Click Assembly="\Prog ram Files\testapp\M essageTest.dll"
      Class="Message" Method="SampleM ethod" />
      </System.Windows. Forms.Button>

      So when I click in button application shoul call method SampleMethod
      in class Message in assembly \Program Files\testapp\M essageTest.dll.
      As you see the xmlnode describe what kind of event I handle.
      When I test HandleEvent method I set:

      button.Click += delegate(object sender1, EventArgs e1)
      { HandleEvents(se nder1, e1, node); };

      where node parameter is is <Click Assembly="\Prog ram Files\testapp
      \MessageTest.dl l" Class="Message" Method="SampleM ethod" />.

      In that case everything works fine. But problem is that buttn is
      creating using reflection in run-time. So I couldn't subscribe to
      Click event as above.

      This is whay I try to use XMLFormsEventAr gs. I have generic delegate
      subscribed to event and when is called I get XmlNode in
      XMLFormsEventAr gs. So I can fire method which I want to fire.

      Comment

      • Ben Voigt [C++ MVP]

        #4
        Re: Event handling and reflection - C# (NetCF)

        Klaudiusz Bryja wrote:
        Hi,
        >
        This is for NetCF 2.0.
        >
        I need to create event handling code which using reflection. I have
        some parameters in XML which describe how event should be handled. I
        have code to create delegate:
        >
        public class DelegateEx
        {
        private object target;
        private MethodInfo method;
        private XmlNode node;
        >
        // XmlNode describe how to handle event (dll path, class, method and
        method parameters).
        private DelegateEx(Meth odInfo method, object target, XmlNode
        node)
        {
        this.target = target;
        this.method = method;
        this.node = node;
        }
        >
        // This is called when event was fired.
        // XMLFormsEventAr gs inherits from EventsArgs and add XmlNode
        property.
        private void Invoke(object sender, EventArgs e)
        {
        method.Invoke(t arget, new object[] { sender, (new
        XMLFormsEventAr gs(this.node, e) as EventArgs) });
        }
        >
        public static EventHandler CreateDelegate( MethodInfo method,
        object target, XmlNode node)
        {
        return new EventHandler((n ew DelegateEx(meth od, target,
        node)).Invoke);
        }
        }
        >
        Using this I try to subscribe to event (I have static method
        HandleEvents which should be called when event is fired):
        >
        EventInfo ei = form.GetType(). GetEvent("Click ",
        BindingFlags.Ig noreCase | BindingFlags.Pu blic | BindingFlags.No nPublic
        >BindingFlags.I nstance | BindingFlags.St atic);
        if (ei != null)
        {
        MethodInfo miHandler = typeof(XMLForms ).GetMethod("Ha ndleEvents",
        BindingFlags.Ig noreCase | BindingFlags.Pu blic | BindingFlags.No nPublic
        >BindingFlags.I nstance | BindingFlags.St atic);
        There's no need to use reflection for HandleEvents, only for the method
        identified in your xml.
        >
        MethodInfo addHandler = ei.GetAddMethod ();
        >
        // formNode - this is xmlNode which describe event
        >
        Object[] addHandlerArgs = { DelegateEx.Crea teDelegate(miHa ndler,
        typeof(XMLForms ), formNode) };
        addHandler.Invo ke(form, addHandlerArgs) ;
        }
        >
        Everything work when I want to handle standard event which is type of
        EventHandler. But I get error "ArgumentExcept ion" without any message
        when I try to handle e.g. KeyDown event (event is type of
        KeyEventHandler ).
        >
        StackTrace for this error:
        at System.Reflecti on.RuntimeMetho dInfo.InternalI nvoke()
        at System.Reflecti on.RuntimeMetho dInfo.InternalI nvoke()
        at System.Reflecti on.RuntimeMetho dInfo.Invoke()
        at System.Reflecti on.MethodBase.I nvoke()
        at bcs.XMLForms.Bu ildXMLForm()
        at TestApp.Form1.b utton2_Click()
        at System.Windows. Forms.Control.O nClick()
        at System.Windows. Forms.Button.On Click()
        at System.Windows. Forms.ButtonBas e.WnProc()
        at System.Windows. Forms.Control._ InternalWnProc( )
        at Microsoft.AGL.F orms.EVL.EnterM ainLoop()
        at System.Windows. Forms.Applicati on.Run()
        at TestApp.Program .Main()
        >
        I think that I should cast EventHandler type to KeyEventHandler type
        but I get error:
        Cannot convert type 'System.EventHa ndler' to
        'System.Windows .Forms.KeyEvent Handler'.
        >
        How to change my code to work with all type of EventHandler?
        Try:

        class XmlEventForward er
        {
        public readonly XmlNode node;
        public XmlEventForward er(XmlNode node) { this.node = node; }
        public void ForwardIncoming (object sender, EventArgs e) {
        XMLForms.Handle Event(sender, e, node); }

        public static readonly MethodInfo forwarder;
        static XmlEventForward er()
        {
        forwarder = typeof(XmlEvent Forwarder).GetM ethod("ForwardI ncoming",|
        BindingFlags.Pu blic | BindingFlags.In stance);
        }
        }

        EventInfo ei = form.GetType(). GetEvent("Click ", BindingFlags.Ig noreCase |
        BindingFlags.Pu blic | BindingFlags.No nPublic | BindingFlags.In stance |
        BindingFlags.St atic);
        if (ei != null)
        {

        MethodInfo addHandler = ei.GetAddMethod ();
        >
        // formNode - this is xmlNode which describe event
        >
        object[] addHandlerArgs = new object[] {
        Delegate.Create Delegate(ei.Eve ntHandlerType, new
        XmlEventForward er(formNode), XmlEventForward er.forwarder) };
        addHandler.Invo ke(form, addHandlerArgs) ;
        }


        When XMLForms.Handle Event calls the method identified in your xml snippet,
        the runtime will ensure that the eventargs actually passed in the event is
        the right type for the handler. Since you're using reflection there, it
        should just happen with no casting required.

        >
        >
        Best regards,
        Klaudiusz

        Comment

        • Klaudiusz Bryja

          #5
          Re: Event handling and reflection - C# (NetCF)

          On 23 Lip, 20:12, "Ben Voigt [C++ MVP]" <r...@nospam.no spamwrote:
          Klaudiusz Bryja wrote:
          Hi,
          >
          This is for NetCF 2.0.
          >
          I need to create event handling code which using reflection. I have
          some parameters in XML which describe how event should be handled. I
          have code to create delegate:
          >
          public class DelegateEx
          {
          private object target;
          private MethodInfo method;
          private XmlNode node;
          >
          // XmlNode describe how to handle event (dll path, class, method and
          method parameters).
          private DelegateEx(Meth odInfo method, object target, XmlNode
          node)
          {
          this.target = target;
          this.method = method;
          this.node = node;
          }
          >
          // This is called when event was fired.
          // XMLFormsEventAr gs inherits from EventsArgs and add XmlNode
          property.
          private void Invoke(object sender, EventArgs e)
          {
          method.Invoke(t arget, new object[] { sender, (new
          XMLFormsEventAr gs(this.node, e) as EventArgs) });
          }
          >
          public static EventHandler CreateDelegate( MethodInfo method,
          object target, XmlNode node)
          {
          return new EventHandler((n ew DelegateEx(meth od, target,
          node)).Invoke);
          }
          }
          >
          Using this I try to subscribe to event (I have static method
          HandleEvents which should be called when event is fired):
          >
          EventInfo ei = form.GetType(). GetEvent("Click ",
          BindingFlags.Ig noreCase | BindingFlags.Pu blic | BindingFlags.No nPublic
          BindingFlags.In stance | BindingFlags.St atic);
          if (ei != null)
          {
          MethodInfo miHandler = typeof(XMLForms ).GetMethod("Ha ndleEvents",
          BindingFlags.Ig noreCase | BindingFlags.Pu blic | BindingFlags.No nPublic
          BindingFlags.In stance | BindingFlags.St atic);
          >
          There's no need to use reflection for HandleEvents, only for the method
          identified in your xml.
          >
          >
          >
          >
          >
          MethodInfo addHandler = ei.GetAddMethod ();
          >
          // formNode - this is xmlNode which describe event
          >
          Object[] addHandlerArgs = { DelegateEx.Crea teDelegate(miHa ndler,
          typeof(XMLForms ), formNode) };
          addHandler.Invo ke(form, addHandlerArgs) ;
          }
          >
          Everything work when I want to handle standard event which is type of
          EventHandler. But I get error "ArgumentExcept ion" without any message
          when I try to handle e.g. KeyDown event (event is type of
          KeyEventHandler ).
          >
          StackTrace for this error:
          at System.Reflecti on.RuntimeMetho dInfo.InternalI nvoke()
          at System.Reflecti on.RuntimeMetho dInfo.InternalI nvoke()
          at System.Reflecti on.RuntimeMetho dInfo.Invoke()
          at System.Reflecti on.MethodBase.I nvoke()
          at bcs.XMLForms.Bu ildXMLForm()
          at TestApp.Form1.b utton2_Click()
          at System.Windows. Forms.Control.O nClick()
          at System.Windows. Forms.Button.On Click()
          at System.Windows. Forms.ButtonBas e.WnProc()
          at System.Windows. Forms.Control._ InternalWnProc( )
          at Microsoft.AGL.F orms.EVL.EnterM ainLoop()
          at System.Windows. Forms.Applicati on.Run()
          at TestApp.Program .Main()
          >
          I think that I should cast EventHandler type to KeyEventHandler type
          but I get error:
          Cannot convert type 'System.EventHa ndler' to
          'System.Windows .Forms.KeyEvent Handler'.
          >
          How to change my code to work with all type of EventHandler?
          >
          Try:
          >
          class XmlEventForward er
          {
          public readonly XmlNode node;
          public XmlEventForward er(XmlNode node) { this.node = node; }
          public void ForwardIncoming (object sender, EventArgs e) {
          XMLForms.Handle Event(sender, e, node); }
          >
          public static readonly MethodInfo forwarder;
          static XmlEventForward er()
          {
          forwarder = typeof(XmlEvent Forwarder).GetM ethod("ForwardI ncoming",|
          BindingFlags.Pu blic | BindingFlags.In stance);
          }
          >
          }
          >
          EventInfo ei = form.GetType(). GetEvent("Click ", BindingFlags.Ig noreCase |
          BindingFlags.Pu blic | BindingFlags.No nPublic | BindingFlags.In stance |
          BindingFlags.St atic);
          if (ei != null)
          {
          >
          MethodInfo addHandler = ei.GetAddMethod ();
          >
          // formNode - this is xmlNode which describe event
          >
          object[] addHandlerArgs = new object[] {
          Delegate.Create Delegate(ei.Eve ntHandlerType, new
          XmlEventForward er(formNode), XmlEventForward er.forwarder) };
          addHandler.Invo ke(form, addHandlerArgs) ;
          >
          }
          >
          When XMLForms.Handle Event calls the method identified in your xml snippet,
          the runtime will ensure that the eventargs actually passed in the event is
          the right type for the handler. Since you're using reflection there, it
          should just happen with no casting required.
          >
          >
          >
          Best regards,
          Klaudiusz
          Hi,

          I try this but main problem is that CF hasn't Delegate.Create Delegate
          (only in full framework or in NetCF 3.5 but I need solution for NetCF
          2.). When I try to use your code I get the same ArgumentExcepti on as
          before (for KeyDown event). I use DelegateEx.Crea teDelegate. I notice
          taht the problem is in type of eventhandler. When I handle Click event
          I pass to AddEventHandler delegate of EventHandler type it's work but
          with KeyDown event don't work. So I try to use KeyEventHandler and
          it's work. The problem is that it should be flexible and I don't know
          how to do it.

          Comment

          • Ben Voigt [C++ MVP]

            #6
            Re: Event handling and reflection - C# (NetCF)

            Hi,
            >
            I try this but main problem is that CF hasn't Delegate.Create Delegate
            (only in full framework or in NetCF 3.5 but I need solution for NetCF
            2.). When I try to use your code I get the same ArgumentExcepti on as
            before (for KeyDown event). I use DelegateEx.Crea teDelegate. I notice
            taht the problem is in type of eventhandler. When I handle Click event
            I pass to AddEventHandler delegate of EventHandler type it's work but
            with KeyDown event don't work. So I try to use KeyEventHandler and
            it's work. The problem is that it should be flexible and I don't know
            how to do it.
            The problem is that creating a delegate is covariant, but there's no
            covariant conversion from one delegate type to another. That's probably why
            support for Delegate.Create Delegate got added in the newer CF.

            You might be able to workaround if you're interested only in the standard
            events of standard controls, by adding directly to the underlying collection
            of handlers if it is more weakly typed. I seem to recall that a Dictionary
            of EventHandler is used, although that might be different on CF as well.

            Or take a look at Delegate.Combin e, although I suspect it also requires that
            both input delegates be the exact same type.


            Comment

            Working...