Existe-t-il un moyen de trouver tous les gestionnaires d'événements pour un contrôle Windows Forms? Des gestionnaires d'événements spécifiquement définis de manière statique?Trouver tous les gestionnaires d'événements pour un contrôle Windows Forms dans .NET
Répondre
Windows Forms a de fortes contre-mesures contre cela. La plupart des contrôles stockent la référence du gestionnaire d'événements dans une liste qui nécessite un "cookie" secret. La valeur du cookie est créée dynamiquement, vous ne pouvez pas le deviner à l'avance. La réflexion est une porte dérobée, vous devez connaître le nom de la variable cookie. Celui de l'événement Control.Click est nommé "EventClick" par exemple, vous pouvez le voir dans la source de référence ou avec Reflector.
Tout cela est incroyablement peu pratique, si vous avez l'impression de faire quelque chose d'imprudent, alors vous êtes sur la bonne voie. Vous pouvez trouver un exemple de code qui fait cela dans ma réponse en this thread.
contrôles Windows Forms utilisent une propriété appelée EventHandlerList
Events
pour tenir les gestionnaires d'événements pour que vous puissiez itérer cette collection. Pour déterminer quels gestionnaires souscrits sont statiques, vous devez utiliser reflection.
Ne voulez-vous pas dire le formulaire lui-même (pas les contrôles)? –
Ou "composants"? –
Ce code obtenir les gestionnaires d'événements pour un contrôle
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
J'ai eu des problèmes avec l'ajout de gestionnaires d'événements plus d'une fois à plusieurs soulevé résultant des événements. Les éléments suivants vous permettront de vérifier si un contrôle a déjà un gestionnaire pour un événement spécifié.
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
"Si vous avez l'impression que vous faites quelque chose d'imprudent, alors vous êtes sur la bonne voie". Je commençais juste à avoir ce sentiment quand j'ai eu votre réponse ici. Merci. Certainement besoin de repenser ce que je fais et pourquoi. Merci pour l'aide. – Jeff
@Hans Passant. J'ai une demande pour répondre à une question similaire. Vous aviez commenté mais pas répondu. Maintenant j'ai mis à jour la question. S'il vous plaît jeter un oeil à http://stackoverflow.com/questions/12174148/alternative-to-pageload-in-wiforms-to-detect-any-event-being-fired-on-a-windows "chaque fois que vous trouvez le temps. – Sami