2016-12-23 1 views
2

は私が遅れて以下のようにバインドさ簡単なMethodeのvb.net後半

Public Sub mysub(sender As Object, e As EventArgs) 

... here i need somehow the name of the event which has been raised 

End sub 

を持って結合用いた方法にeventnameに渡します何らかの理由でmysubにsystem.evenandleのバインディングプロセスがあるので、イベントによって呼び出されたときにmysub内でイベント名を取得できますか?

+0

これは「A/B問題」と思われます。あなたはなぜこれを行う必要があるかについて私たちにもっと教えていただけますか? –

+0

私のアプリケーションの中では、イベントとメソッドは設定ファイルと一緒に保存されます。したがって、私は実行時にどの組み合わせが設定されているかわかりません。同じオブジェクトが同じメソッドを2回含んでいて、異なるイベントを使用している(つまり、入力して離れる)場合は、メソッドを呼び出すイベントがわからないと、辞書に格納された特定のメソッドのパラメータを取得できません。 thur for ur help – skrskr

+0

問題は、メソッドの名前とイベントの名前と、そのメソッドを使って前記イベントを処理する方法と、メソッド内でどのイベントが発生したかを何らかの形で知ることである。これは正しいです? – djv

答えて

1

これは深刻なリファクタリングを必要としますが、うまく機能するようになりました。

匿名メソッドをイベントのダイレクトイベントハンドラとして使用します。このメソッドは、イベントの名前と実際のハンドラを取得し、別のプロキシイベントハンドラに渡します。そのプロキシは実際のハンドラを呼び出し、キャプチャされたイベントの名前を渡します。

Imports System.Reflection 

Public Class Form1 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load 

     Dim list As New List(Of HandlerInfo) 
     list.Add(New HandlerInfo() With {.EventName = "Click", .HandlerName = "mysub"}) 
     list.Add(New HandlerInfo() With {.EventName = "MouseEnter", .HandlerName = "mysub"}) 
     list.Add(New HandlerInfo() With {.EventName = "MouseLeave", .HandlerName = "mysub"}) 

     For Each info As HandlerInfo In list 
      Dim eventName As String = info.EventName 'Use local variables, rather that the iterator, or else the wrong object will get captured and it won't work correctly. 
      Dim handlerName As String = info.HandlerName 

      Dim dynamicEventInfo As EventInfo = Button1.GetType.GetEvent(eventName) 
      dynamicEventInfo.AddEventHandler(Button1, New EventHandler(Sub(sender2 As Object, e2 As EventArgs) 
                      Dim t As Type = GetType(Form1) 'This is the type of the object that contains the handler 
                      Dim i As Object = Me 'This is the instance of "t" that the handler should be invoked on 
                      Dim handler As MethodInfo = t.GetMethod(handlerName) 
                      handler.Invoke(i, New Object() {sender2, e2, eventName}) 
                     End Sub)) 
     Next 
    End Sub 

    Private Class HandlerInfo 
     Public Property EventName As String 
     Public Property HandlerName As String 
    End Class 

    Public Sub mysub(sender As Object, e As EventArgs, eventName As String) 
     Debug.WriteLine(eventName) 
    End Sub 
End Class 
+0

ありがとうございます。それはショットを取得しますが、それはしばらく時間がかかるでしょう。多く! – skrskr

+0

私はそれをリファクタしてプロキシハンドラをインライン化しました。 –

+0

私はそれをどうやって行ったか分かりませんでしたが..... ITは素晴らしいです!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! – skrskr

0

残念なことに、私は良いと思うことはできませんこれを行う方法。

これは、あなたのメソッドがEventArgsTypeからイベント名を推測できる可能性があります。しかし、これは間違いなくすべての場合に機能しません。

また、リフレクションを使用してコールスタックを調べることもできます。 .NET WinFormsでは、イベントの一般的な規則は、 "On {EventName}"というメソッドから呼び出されることです。したがって、ClickイベントはOnClickから発生します。呼び出しスタックの前のフレーム。イベントハンドラ内にある場合、にはにそのメソッドの名前が必要です。その名前を解析してイベント名を判別できます。コード作成者がその規約に従ったという保証はなく、誰かがイベント以外の場所から手作業でハンドラを起動していないという保証はありません。

コールスタックの例は、Clickイベント内のボタンの下の画像にあります。 enter image description here

パフォーマンスクリティカルなコードでこのメソッドを使用することは間違いありません。

+0

コールスタックには、イベント名 – djv

+1

Correntではなく、メソッド名が表示されます(この場合は "OnClick")。私が言ったように、共通の規約では、このメソッド名は "on"にイベントの名前を加えたもので、この場合は "Click"というイベント名です。イベントを取得するには、そのメソッド名を解析する必要があります。私はそれが良い*解決策ではないと具体的に言いましたが、それがあなたがイベント名を得ることができると思う唯一のことです。 –

+0

私たちが知っている限り、あなたは正しいと思いますし、 "mysub"は本当に "OnLeave"ですが、そうでなければメソッド名を変更しています。イベントに 'EventName'パラメータを追加するか、そのプロパティを持つカスタムEventArgs。 – djv

関連する問題