Find all event handlers for a Windows Forms control in .NET

后端 未结 3 1027
余生分开走
余生分开走 2020-12-20 03:24

Is there a way to find all event handlers for a Windows Forms control? Specifically statically defined event handlers?

相关标签:
3条回答
  • 2020-12-20 03:51

    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.

    0 讨论(0)
  • 2020-12-20 03:52

    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.

    0 讨论(0)
  • 2020-12-20 04:07

    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
    
    0 讨论(0)
提交回复
热议问题