トップ回答者
イベントの存在チェック

質問
回答
-
海鶏さんこんにちは
以下のURLを参考に作ってみました。
http://www.technewsgroups.net/group/microsoft.public.dotnet.general/topic4196.aspx
試されるときはForm1にボタンを2つ作ってください。
Button2のClickイベントのハンドラが2つであることが検出できます。
Code SnippetImports system.componentmodel
Imports system.ReflectionPublic Class Form1
Private Shared ReadOnly Property All() As BindingFlags
Get
Return BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.IgnoreCase Or BindingFlags.Static
End Get
End PropertyPrivate Shared Function GetEventsMethod(ByVal objType As Type) As MethodInfo
Dim mi As MethodInfo = objType.GetMethod("get_Events", All)
If mi Is Nothing And Not (objType.BaseType Is Nothing) Then
mi = GetEventsMethod(objType.BaseType)
End If
Return mi
End Function 'GetEventsMethodPrivate Shared Function GetEvents(ByVal obj As Object) As EventHandlerList
Dim mi As MethodInfo = GetEventsMethod(obj.GetType())
If mi Is Nothing Then Return Nothing
Return CType(mi.Invoke(obj, New Object() {}), EventHandlerList)
End Function 'GetEventsPrivate Shared Function GetEventIDField(ByVal objType As Type, ByVal eventName As String) As FieldInfo
Dim fi As FieldInfo = objType.GetField("Event" + eventName, All)
If fi Is Nothing And Not (objType.BaseType Is Nothing) Then
fi = GetEventIDField(objType.BaseType, eventName)
End If
Return fi
End Function 'GetEventIDFieldPrivate Shared Function GetEventID(ByVal obj As Object, ByVal eventName As String) As Object
Dim fi As FieldInfo = GetEventIDField(obj.GetType(), eventName)
If fi Is Nothing Then Return Nothing
Return fi.GetValue(obj)
End Function 'GetEventIDPrivate Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim list As EventHandlerList = GetEvents(Button2)
Dim key As Object = GetEventID(Button2, "Click")
Debug.Print(list(key).GetInvocationList.GetLength(0).ToString)
End SubPrivate Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click, Button2.Click
'ダミー
End Sub
End Classもし、海鶏さんが既にC#のコードサンプルを見つけておられたのであれば、例えば以下のURLを使ってVisual Basicに変換してみることができます。
http://authors.aspalliance.com/aldotnet/examples/translate.aspx
すべての返信
-
海鶏さんこんにちは
以下のURLを参考に作ってみました。
http://www.technewsgroups.net/group/microsoft.public.dotnet.general/topic4196.aspx
試されるときはForm1にボタンを2つ作ってください。
Button2のClickイベントのハンドラが2つであることが検出できます。
Code SnippetImports system.componentmodel
Imports system.ReflectionPublic Class Form1
Private Shared ReadOnly Property All() As BindingFlags
Get
Return BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.IgnoreCase Or BindingFlags.Static
End Get
End PropertyPrivate Shared Function GetEventsMethod(ByVal objType As Type) As MethodInfo
Dim mi As MethodInfo = objType.GetMethod("get_Events", All)
If mi Is Nothing And Not (objType.BaseType Is Nothing) Then
mi = GetEventsMethod(objType.BaseType)
End If
Return mi
End Function 'GetEventsMethodPrivate Shared Function GetEvents(ByVal obj As Object) As EventHandlerList
Dim mi As MethodInfo = GetEventsMethod(obj.GetType())
If mi Is Nothing Then Return Nothing
Return CType(mi.Invoke(obj, New Object() {}), EventHandlerList)
End Function 'GetEventsPrivate Shared Function GetEventIDField(ByVal objType As Type, ByVal eventName As String) As FieldInfo
Dim fi As FieldInfo = objType.GetField("Event" + eventName, All)
If fi Is Nothing And Not (objType.BaseType Is Nothing) Then
fi = GetEventIDField(objType.BaseType, eventName)
End If
Return fi
End Function 'GetEventIDFieldPrivate Shared Function GetEventID(ByVal obj As Object, ByVal eventName As String) As Object
Dim fi As FieldInfo = GetEventIDField(obj.GetType(), eventName)
If fi Is Nothing Then Return Nothing
Return fi.GetValue(obj)
End Function 'GetEventIDPrivate Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim list As EventHandlerList = GetEvents(Button2)
Dim key As Object = GetEventID(Button2, "Click")
Debug.Print(list(key).GetInvocationList.GetLength(0).ToString)
End SubPrivate Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click, Button2.Click
'ダミー
End Sub
End Classもし、海鶏さんが既にC#のコードサンプルを見つけておられたのであれば、例えば以下のURLを使ってVisual Basicに変換してみることができます。
http://authors.aspalliance.com/aldotnet/examples/translate.aspx
-
サンプルコードありがとうございます。
リフレクションを利用すればいいのとイベントの実装方法により取得方法が違うというのが理解できました。
私が想定していたC#のコードは以下のもので。このような分岐をやりたかったのです。
Code Snippetif(this.OnKeyDown != null)
this.OnKeyDown(eventCode);
}今回はEventHandlerのみなので以下の感じでどうにかできそうです。
Formにボタン1個のサンプル
Code SnippetImports System.Reflection
Public Class Form1
Public Class EventTest
Public Event Event1 As EventHandler
Public Event Event2 As EventHandler
Public Function IsRegistEvent1() As Boolean
Return Not Event1Event Is Nothing
End Function
Public Function IsRegistEvent2() As Boolean
Return Not Event2Event Is Nothing
End Function
End Class
Public Function IsRegistEvent(ByVal o As Object, ByVal eventName As String) As Boolean
Dim AllBindingFlags As BindingFlags = BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.IgnoreCase Or BindingFlags.Static Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.IgnoreCase Or BindingFlags.Static
Dim fi As System.Reflection.FieldInfo = o.GetType.GetField(eventName & "Event", AllBindingFlags)
Dim value As Object = fi.GetValue(o)
If value Is Nothing Then
Return False
Else
Return True
End If
End FunctionPrivate Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim et As EventTest = New EventTest
AddHandler et.event1, AddressOf Button1_ClickDebug.WriteLine(IsRegistEvent(et, "Event1"))
Debug.WriteLine(IsRegistEvent(et, "Event2"))
Debug.WriteLine(et.IsRegistEvent1)
Debug.WriteLine(et.IsRegistEvent2)
End SubEnd Class