|
From: Klaudiusz Bryja on 23 Jul 2008 04:28 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(MethodInfo method, object target, XmlNode node) { this.target = target; this.method = method; this.node = node; } // This is called when event was fired. // XMLFormsEventArgs inherits from EventsArgs and add XmlNode property. private void Invoke(object sender, EventArgs e) { method.Invoke(target, new object[] { sender, (new XMLFormsEventArgs(this.node, e) as EventArgs) }); } public static EventHandler CreateDelegate(MethodInfo method, object target, XmlNode node) { return new EventHandler((new DelegateEx(method, 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.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); if (ei != null) { MethodInfo miHandler = typeof(XMLForms).GetMethod("HandleEvents", BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); MethodInfo addHandler = ei.GetAddMethod(); // formNode - this is xmlNode which describe event Object[] addHandlerArgs = { DelegateEx.CreateDelegate(miHandler, typeof(XMLForms), formNode) }; addHandler.Invoke(form, addHandlerArgs); } Everything work when I want to handle standard event which is type of EventHandler. But I get error "ArgumentException" without any message when I try to handle e.g. KeyDown event (event is type of KeyEventHandler). StackTrace for this error: at System.Reflection.RuntimeMethodInfo.InternalInvoke() at System.Reflection.RuntimeMethodInfo.InternalInvoke() at System.Reflection.RuntimeMethodInfo.Invoke() at System.Reflection.MethodBase.Invoke() at bcs.XMLForms.BuildXMLForm() at TestApp.Form1.button2_Click() at System.Windows.Forms.Control.OnClick() at System.Windows.Forms.Button.OnClick() at System.Windows.Forms.ButtonBase.WnProc() at System.Windows.Forms.Control._InternalWnProc() at Microsoft.AGL.Forms.EVL.EnterMainLoop() at System.Windows.Forms.Application.Run() at TestApp.Program.Main() I think that I should cast EventHandler type to KeyEventHandler type but I get error: Cannot convert type 'System.EventHandler' to 'System.Windows.Forms.KeyEventHandler'. How to change my code to work with all type of EventHandler? Best regards, Klaudiusz
From: Pavel Minaev on 23 Jul 2008 05:32 On Jul 23, 12:28 pm, Klaudiusz Bryja <bryja_klaudi...(a)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(MethodInfo method, object target, XmlNode > node) > { > this.target = target; > this.method = method; > this.node = node; > } > > // This is called when event was fired. > // XMLFormsEventArgs inherits from EventsArgs and add XmlNode > property. > private void Invoke(object sender, EventArgs e) > { > method.Invoke(target, new object[] { sender, (new > XMLFormsEventArgs(this.node, e) as EventArgs) }); > } > > public static EventHandler CreateDelegate(MethodInfo method, > object target, XmlNode node) > { > return new EventHandler((new DelegateEx(method, 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.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic > | BindingFlags.Instance | BindingFlags.Static); > if (ei != null) > { > MethodInfo miHandler = typeof(XMLForms).GetMethod("HandleEvents", > BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic > | BindingFlags.Instance | BindingFlags.Static); > > MethodInfo addHandler = ei.GetAddMethod(); > > // formNode - this is xmlNode which describe event > > Object[] addHandlerArgs = { DelegateEx.CreateDelegate(miHandler, > typeof(XMLForms), formNode) }; > addHandler.Invoke(form, addHandlerArgs); > > } > > Everything work when I want to handle standard event which is type of > EventHandler. But I get error "ArgumentException" without any message > when I try to handle e.g. KeyDown event (event is type of > KeyEventHandler). > > StackTrace for this error: > at System.Reflection.RuntimeMethodInfo.InternalInvoke() > at System.Reflection.RuntimeMethodInfo.InternalInvoke() > at System.Reflection.RuntimeMethodInfo.Invoke() > at System.Reflection.MethodBase.Invoke() > at bcs.XMLForms.BuildXMLForm() > at TestApp.Form1.button2_Click() > at System.Windows.Forms.Control.OnClick() > at System.Windows.Forms.Button.OnClick() > at System.Windows.Forms.ButtonBase.WnProc() > at System.Windows.Forms.Control._InternalWnProc() > at Microsoft.AGL.Forms.EVL.EnterMainLoop() > at System.Windows.Forms.Application.Run() > at TestApp.Program.Main() > > I think that I should cast EventHandler type to KeyEventHandler type > but I get error: > Cannot convert type 'System.EventHandler' to > 'System.Windows.Forms.KeyEventHandler'. > > How to change my code to work with all type of EventHandler? Your code passes your own class XMLFormsEventArgs 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?
From: Klaudiusz Bryja on 23 Jul 2008 06:09 On 23 Lip, 11:32, Pavel Minaev <int...(a)gmail.com> wrote: > On Jul 23, 12:28 pm, Klaudiusz Bryja <bryja_klaudi...(a)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(MethodInfo method, object target, XmlNode > > node) > > { > > this.target = target; > > this.method = method; > > this.node = node; > > } > > > // This is called when event was fired. > > // XMLFormsEventArgs inherits from EventsArgs and add XmlNode > > property. > > private void Invoke(object sender, EventArgs e) > > { > > method.Invoke(target, new object[] { sender, (new > > XMLFormsEventArgs(this.node, e) as EventArgs) }); > > } > > > public static EventHandler CreateDelegate(MethodInfo method, > > object target, XmlNode node) > > { > > return new EventHandler((new DelegateEx(method, 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.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic > > | BindingFlags.Instance | BindingFlags.Static); > > if (ei != null) > > { > > MethodInfo miHandler = typeof(XMLForms).GetMethod("HandleEvents", > > BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic > > | BindingFlags.Instance | BindingFlags.Static); > > > MethodInfo addHandler = ei.GetAddMethod(); > > > // formNode - this is xmlNode which describe event > > > Object[] addHandlerArgs = { DelegateEx.CreateDelegate(miHandler, > > typeof(XMLForms), formNode) }; > > addHandler.Invoke(form, addHandlerArgs); > > > } > > > Everything work when I want to handle standard event which is type of > > EventHandler. But I get error "ArgumentException" without any message > > when I try to handle e.g. KeyDown event (event is type of > > KeyEventHandler). > > > StackTrace for this error: > > at System.Reflection.RuntimeMethodInfo.InternalInvoke() > > at System.Reflection.RuntimeMethodInfo.InternalInvoke() > > at System.Reflection.RuntimeMethodInfo.Invoke() > > at System.Reflection.MethodBase.Invoke() > > at bcs.XMLForms.BuildXMLForm() > > at TestApp.Form1.button2_Click() > > at System.Windows.Forms.Control.OnClick() > > at System.Windows.Forms.Button.OnClick() > > at System.Windows.Forms.ButtonBase.WnProc() > > at System.Windows.Forms.Control._InternalWnProc() > > at Microsoft.AGL.Forms.EVL.EnterMainLoop() > > at System.Windows.Forms.Application.Run() > > at TestApp.Program.Main() > > > I think that I should cast EventHandler type to KeyEventHandler type > > but I get error: > > Cannot convert type 'System.EventHandler' to > > 'System.Windows.Forms.KeyEventHandler'. > > > How to change my code to work with all type of EventHandler? > > Your code passes your own class XMLFormsEventArgs 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? XMLFormsEventArgs 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="\Program Files\testapp\MessageTest.dll" Class="Message" Method="SampleMethod" /> </System.Windows.Forms.Button> So when I click in button application shoul call method SampleMethod in class Message in assembly \Program Files\testapp\MessageTest.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(sender1, e1, node); }; where node parameter is is <Click Assembly="\Program Files\testapp \MessageTest.dll" Class="Message" Method="SampleMethod" />. 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 XMLFormsEventArgs. I have generic delegate subscribed to event and when is called I get XmlNode in XMLFormsEventArgs. So I can fire method which I want to fire.
From: Ben Voigt [C++ MVP] on 23 Jul 2008 14:12 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(MethodInfo method, object target, XmlNode > node) > { > this.target = target; > this.method = method; > this.node = node; > } > > // This is called when event was fired. > // XMLFormsEventArgs inherits from EventsArgs and add XmlNode > property. > private void Invoke(object sender, EventArgs e) > { > method.Invoke(target, new object[] { sender, (new > XMLFormsEventArgs(this.node, e) as EventArgs) }); > } > > public static EventHandler CreateDelegate(MethodInfo method, > object target, XmlNode node) > { > return new EventHandler((new DelegateEx(method, 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.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic >> BindingFlags.Instance | BindingFlags.Static); > if (ei != null) > { > MethodInfo miHandler = typeof(XMLForms).GetMethod("HandleEvents", > BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic >> BindingFlags.Instance | BindingFlags.Static); 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.CreateDelegate(miHandler, > typeof(XMLForms), formNode) }; > addHandler.Invoke(form, addHandlerArgs); > } > > Everything work when I want to handle standard event which is type of > EventHandler. But I get error "ArgumentException" without any message > when I try to handle e.g. KeyDown event (event is type of > KeyEventHandler). > > StackTrace for this error: > at System.Reflection.RuntimeMethodInfo.InternalInvoke() > at System.Reflection.RuntimeMethodInfo.InternalInvoke() > at System.Reflection.RuntimeMethodInfo.Invoke() > at System.Reflection.MethodBase.Invoke() > at bcs.XMLForms.BuildXMLForm() > at TestApp.Form1.button2_Click() > at System.Windows.Forms.Control.OnClick() > at System.Windows.Forms.Button.OnClick() > at System.Windows.Forms.ButtonBase.WnProc() > at System.Windows.Forms.Control._InternalWnProc() > at Microsoft.AGL.Forms.EVL.EnterMainLoop() > at System.Windows.Forms.Application.Run() > at TestApp.Program.Main() > > I think that I should cast EventHandler type to KeyEventHandler type > but I get error: > Cannot convert type 'System.EventHandler' to > 'System.Windows.Forms.KeyEventHandler'. > > How to change my code to work with all type of EventHandler? Try: class XmlEventForwarder { public readonly XmlNode node; public XmlEventForwarder(XmlNode node) { this.node = node; } public void ForwardIncoming(object sender, EventArgs e) { XMLForms.HandleEvent(sender, e, node); } public static readonly MethodInfo forwarder; static XmlEventForwarder() { forwarder = typeof(XmlEventForwarder).GetMethod("ForwardIncoming",| BindingFlags.Public | BindingFlags.Instance); } } EventInfo ei = form.GetType().GetEvent("Click", BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); if (ei != null) { MethodInfo addHandler = ei.GetAddMethod(); > > // formNode - this is xmlNode which describe event > object[] addHandlerArgs = new object[] { Delegate.CreateDelegate(ei.EventHandlerType, new XmlEventForwarder(formNode), XmlEventForwarder.forwarder) }; addHandler.Invoke(form, addHandlerArgs); } When XMLForms.HandleEvent 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
From: Klaudiusz Bryja on 24 Jul 2008 03:45 On 23 Lip, 20:12, "Ben Voigt [C++ MVP]" <r...(a)nospam.nospam> wrote: > 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(MethodInfo method, object target, XmlNode > > node) > > { > > this.target = target; > > this.method = method; > > this.node = node; > > } > > > // This is called when event was fired. > > // XMLFormsEventArgs inherits from EventsArgs and add XmlNode > > property. > > private void Invoke(object sender, EventArgs e) > > { > > method.Invoke(target, new object[] { sender, (new > > XMLFormsEventArgs(this.node, e) as EventArgs) }); > > } > > > public static EventHandler CreateDelegate(MethodInfo method, > > object target, XmlNode node) > > { > > return new EventHandler((new DelegateEx(method, 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.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic > >> BindingFlags.Instance | BindingFlags.Static); > > if (ei != null) > > { > > MethodInfo miHandler = typeof(XMLForms).GetMethod("HandleEvents", > > BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic > >> BindingFlags.Instance | BindingFlags.Static); > > 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.CreateDelegate(miHandler, > > typeof(XMLForms), formNode) }; > > addHandler.Invoke(form, addHandlerArgs); > > } > > > Everything work when I want to handle standard event which is type of > > EventHandler. But I get error "ArgumentException" without any message > > when I try to handle e.g. KeyDown event (event is type of > > KeyEventHandler). > > > StackTrace for this error: > > at System.Reflection.RuntimeMethodInfo.InternalInvoke() > > at System.Reflection.RuntimeMethodInfo.InternalInvoke() > > at System.Reflection.RuntimeMethodInfo.Invoke() > > at System.Reflection.MethodBase.Invoke() > > at bcs.XMLForms.BuildXMLForm() > > at TestApp.Form1.button2_Click() > > at System.Windows.Forms.Control.OnClick() > > at System.Windows.Forms.Button.OnClick() > > at System.Windows.Forms.ButtonBase.WnProc() > > at System.Windows.Forms.Control._InternalWnProc() > > at Microsoft.AGL.Forms.EVL.EnterMainLoop() > > at System.Windows.Forms.Application.Run() > > at TestApp.Program.Main() > > > I think that I should cast EventHandler type to KeyEventHandler type > > but I get error: > > Cannot convert type 'System.EventHandler' to > > 'System.Windows.Forms.KeyEventHandler'. > > > How to change my code to work with all type of EventHandler? > > Try: > > class XmlEventForwarder > { > public readonly XmlNode node; > public XmlEventForwarder(XmlNode node) { this.node = node; } > public void ForwardIncoming(object sender, EventArgs e) { > XMLForms.HandleEvent(sender, e, node); } > > public static readonly MethodInfo forwarder; > static XmlEventForwarder() > { > forwarder = typeof(XmlEventForwarder).GetMethod("ForwardIncoming",| > BindingFlags.Public | BindingFlags.Instance); > } > > } > > EventInfo ei = form.GetType().GetEvent("Click", BindingFlags.IgnoreCase | > BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | > BindingFlags.Static); > if (ei != null) > { > > MethodInfo addHandler = ei.GetAddMethod(); > > > // formNode - this is xmlNode which describe event > > object[] addHandlerArgs = new object[] { > Delegate.CreateDelegate(ei.EventHandlerType, new > XmlEventForwarder(formNode), XmlEventForwarder.forwarder) }; > addHandler.Invoke(form, addHandlerArgs); > > } > > When XMLForms.HandleEvent 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.CreateDelegate (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 ArgumentException as before (for KeyDown event). I use DelegateEx.CreateDelegate. 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.
|
Next
|
Last
Pages: 1 2 Prev: Consistant Hashing Between WM6 and Desktop Next: Locking / Unlocking Device |