Find all event handlers for a Windows Forms control in .NET
Is there a way to find all event handlers for a Windows Forms control? Specifically staticall开发者_JAVA技巧y defined event handlers?
Windows Forms has strong counter-measures against doing this. Most controls store the event handler reference in a list that requires a secret 'cookie'. The cookie value is dynamically created, you cannot guess it up front. Reflection is a backdoor, you have to know the cookie variable name. The one for the Control.Click event is named "EventClick" for example, you can see this in the Reference Source or with Reflector.
This is all incredibly unpractical, if you're getting the feeling you are doing something unwise then you're on the right track. You can find sample code that does this in my answer in this thread.
Windows Forms controls use an EventHandlerList
property called Events
to hold event handlers so you could iterate that collection. To determine which subscribed handlers are static, you will need to use reflection.
This code will get the event handlers for a control
Private Function getEventHandlers(ctrl As Control) As System.ComponentModel.EventHandlerList
Dim value As System.ComponentModel.EventHandlerList = Nothing
Try
Dim propInfo As System.Reflection.PropertyInfo = GetType(Control).GetProperty("Events", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Static)
If propInfo IsNot Nothing Then value = CType(propInfo.GetValue(ctrl), System.ComponentModel.EventHandlerList)
Catch ex As Exception
End Try
Return value
End Function
I have had problems with adding event handlers more than once resulting in multiple raised events. The following will allow you to check whether a control already has a handler for a specified event.
Private Function hasEventHandler(ctrl As Control, Optional eventName As String = "Click") As Boolean
Dim value As Boolean = False
Try
Dim handlerList As System.ComponentModel.EventHandlerList = getEventHandlers(ctrl)
Dim controlEventInfo As System.Reflection.FieldInfo = GetType(Control).GetField("Event" + eventName, Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static)
If controlEventInfo IsNot Nothing Then
Dim eventKey As Object = controlEventInfo.GetValue(ctrl)
Dim EventHandlerDelegate As [Delegate] = handlerList.Item(eventKey)
If EventHandlerDelegate IsNot Nothing Then value = True
End If
Catch ex As Exception
End Try
Return value
End Function
精彩评论