Instead of hard-coding all conceivable events handlers, is there a way to do this dynamically at runtime?
What I'm trying to do is define a dynamic method and a dynamic delegate at run-time to handle any conceivable event possible in VB.Net. I'm able to tell an event was triggered and the source object, but I'm not able to tell what event was triggered.
What I'm using now correctly handles most basic events that I'm aware of. However, there's no way to tell me what specific event was triggered. All my handling sub (Trigger_Event() as a partial example below) knows is sender As Object, e As EventArgs
. sender
is the object that spawned the event, but it will not tell me what even was triggered. EventArgs
could be extended, but it will never contain the name of the event as that is not standard practice.
Below are two example class subs currently capable of handling most System.Windows.Forms events that I'm aware of where the event args type can be converted to the standard EventArgs type. Announce_Events()
is used to name an event I want to listen to, and fakes a delegate at run-time and currently routes all events to Triggered_Event()
...
Public Sub Announce_Events(event_name As String)
Dim obj_type = _a_specific_object.GetType()
Dim obj_event_info = obj_type.GetEvent(event_name, BindingFlags.Instance OR BindingFlags.Public)
Dim obj_event_delegate As [Delegate] = [Delegate].CreateDelegate(obj_event_info.EventHandlerType, Me, "Triggered_Event")
obj_event_info.AddEventHandler(_a_specific_object, obj_event_delegate)
obj_event_delegate = Nothing
End Sub
Private Sub Triggered_Event(sender As Object, e As EventArgs)
' Handle triggered event here
End Sub
I'm having trouble understanding dynamic methods to handle events. Perhaps there's specific function wording I can use to define my handling method at run-time? How can I word Sub Announce_Events() to tell Triggered_Event() what event name was triggered?
Note: all delegates and methods must be dynamically defined in my case unless a single delegate and method can be defined to handle all conceivable events.
Update: Solved by using either solution given by MarkJ and Hans Passant. Here's both versions...
Anon Sub:
Public Sub Announce_Events(event_name As String)
Dim obj_type = _a_specific_object.GetType()
Dim obj_event_info = obj_type.GetEvent(event_name, BindingFlags.Instance OR BindingFlags.Public)
Dim my_event_handler as EventHandler = Sub (sender As Object, e As Object)
' do something with sender, e, and event_name variables here '
End Sub
obj_event_info.AddEventHandler(_a_specific_object, my_event_handler)
End Sub
Defining the Triggered_Event sub is not necessary. However, still need a way to dynamically cast my_event_handler to obj_event_info.EventHandlerType as otherwise it will only work if obj_event_info.EventHandlerType can narrowly convert to EventHandler.
Worker Object:
Public Sub Announce_Events(event_name As String)
Dim obj_type = _a_specific_object.GetType()
Dim obj_event_info = obj_type.GetEvent(event_name, BindingFlags.Instance OR BindingFlags.Public)
Dim e_worker as new Event_Worker(event_name)
Dim obj_event_delegate = [Delegate].CreateDelegate(obj_event_info.EventHandlerType, e_worker, "Triggered_Event")
obj_event_info.AddEventHandler(_a_specific_object, obj_event_delegate)
End Sub
Event_Worker class has an 'event name' field for reference on event fire, and contains the "Triggered_Event" sub for processing the fired event while passing along 'event name'. However, "Triggered_Event" must be declared to accept 'e' as strict type 'EventArgs' or at least a narrowing conversion.