Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I raise an event via reflection in .NET/C#?

I have a third-party editor that basically comprises a textbox and a button (the DevExpress ButtonEdit control). I want to make a particular keystroke (Alt + Down) emulate clicking the button. In order to avoid writing this over and over, I want to make a generic KeyUp event handler that will raise the ButtonClick event. Unfortunately, there doesn't seem to be a method in the control that raises the ButtonClick event, so...

How do I raise the event from an external function via reflection?

like image 364
Josh Kodroff Avatar asked Oct 13 '08 18:10

Josh Kodroff


People also ask

Where do we use reflection in C#?

You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. If you are using attributes in your code, reflection enables you to access them.

How do you raise an event in C#?

Raising an events is a simple step. First you check the event agaist a null value to ensure that the caller has registered with the event, and then you fire the event by specifying the event by name as well as any required parameters as defined by the associated delegate. MyEvent(message);

Is it good to use reflection in C#?

Some of the situations when reflections are useful in C# are given as follows: Reflections are quite useful for creating new types at runtime. It is easy to use reflection with the program metadata attributes. Reflection is needed to examine and instantiate types in an assembly.

What is reflection in C# Geeksforgeeks?

Reflection is the process of describing the metadata of types, methods and fields in a code. The namespace System.Reflection enables you to obtain data about the loaded assemblies, the elements within them like classes, methods and value types.


2 Answers

Here's a demo using generics (error checks omitted):

using System; using System.Reflection; static class Program {   private class Sub {     public event EventHandler<EventArgs> SomethingHappening;   }   internal static void Raise<TEventArgs>(this object source, string eventName, TEventArgs eventArgs) where TEventArgs : EventArgs   {     var eventDelegate = (MulticastDelegate)source.GetType().GetField(eventName, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(source);     if (eventDelegate != null)     {       foreach (var handler in eventDelegate.GetInvocationList())       {         handler.Method.Invoke(handler.Target, new object[] { source, eventArgs });       }     }   }   public static void Main()   {     var p = new Sub();     p.Raise("SomethingHappening", EventArgs.Empty);     p.SomethingHappening += (o, e) => Console.WriteLine("Foo!");     p.Raise("SomethingHappening", EventArgs.Empty);     p.SomethingHappening += (o, e) => Console.WriteLine("Bar!");     p.Raise("SomethingHappening", EventArgs.Empty);     Console.ReadLine();   } } 
like image 90
Wiebe Cnossen Avatar answered Sep 28 '22 01:09

Wiebe Cnossen


In general, you can't. Think of events as basically pairs of AddHandler/RemoveHandler methods (as that's basically what what they are). How they're implemented is up to the class. Most WinForms controls use EventHandlerList as their implementation, but your code will be very brittle if it starts fetching private fields and keys.

Does the ButtonEdit control expose an OnClick method which you could call?

Footnote: Actually, events can have "raise" members, hence EventInfo.GetRaiseMethod. However, this is never populated by C# and I don't believe it's in the framework in general, either.

like image 23
Jon Skeet Avatar answered Sep 28 '22 02:09

Jon Skeet