Hi!
Ich hab hier einen Code aussm Internet, wo mit Reflection.Emit ein Delegat gebastelt wird, der zu einem beliebiges Event passt, und in dessen Methode eine annere Methode aufgerufen wird. Der Typ des Events wird als Argument gegeben, und ebenso ein MethodInfo der aufzurufenden Methode.
Das Manko: Das MethodInfo kann nur eine Action-Methode sein, also ohne Parameter und ohne Rückgabewert.
Ich hätte nun gerne eine Verbesserung, dass man einen richtigen EventHandler angeben kann, entweder auch in Form eines MethodInfos, aber mw. auch gerne als Delegat.
Sinn der Sache ist für Wpf - damit könnte ich einen Event-Umleiter basteln, der Events vom View ins Viewmodel leitet - das geht nämlich derzeit in Wpf nicht.
Es gibt bereits derlei Lösungen, aber dazu müsste ich extra eine WpfToolkit-Dll mitliefern, und die ist auch nicht so komfortabel und performant wie das Teil, an dem ich grad sitze.
Also mein Problem ist "einfach" zeile#36, wo das MethodInfo aufgerufen wird.
Wie wäre das zu gestalten, wenn das MethodInfo nicht eine leere Action beschreibt, sondern etwa eine Action(Of MouseEventArgs), oder gleich die ganze MouseEventHandler-Signatur?
Und das eben flexibel, also dassich auch einen KeyDownEventhandler angeben kann, und der ruft mit den richtigen Parametern auf?
Wenn sich jmd. da reinknien mag - ich kann auch eine TestSolution aufsetzen, mit der bisherigen Funktionalität, und auch der neuen Funktionalität, unter Auslassung dieses fehlenden Details.
Falls gewünscht - die TestSolution in Wpf oder in Winforms?
Ich hab hier einen Code aussm Internet, wo mit Reflection.Emit ein Delegat gebastelt wird, der zu einem beliebiges Event passt, und in dessen Methode eine annere Methode aufgerufen wird. Der Typ des Events wird als Argument gegeben, und ebenso ein MethodInfo der aufzurufenden Methode.
VB.NET-Quellcode
- ''' <summary>
- ''' erzeugt mit Reflection.Emit einen aufruffähigen Delegaten, der das angegebene Event abonnieren könnte, und der dann methodToInvoke aufruft.
- ''' </summary>
- Public Shared Function CreateDelegate(ByVal eventHandlerType As Type, ByVal method As MethodInfo, ByVal methodOwner As Object) As [Delegate]
- 'Get the eventHandlerType signature
- Dim handlerMethod = eventHandlerType.GetMethod("Invoke")
- If handlerMethod.ReturnParameter.ParameterType IsNot GetType(System.Void) Then
- Throw New ApplicationException("Delegate has a return type. This only supprts event handlers that are void")
- End If
- Dim handlerParams As ParameterInfo() = handlerMethod.GetParameters()
- 'Get the list of type of parameters. Please note that we do + 1 because we have to push the object where the method resides i.e methodInvoker parameter
- Dim dynamicParamTypes As Type() = New Type(handlerParams.Length) {}
- dynamicParamTypes(0) = methodOwner.[GetType]()
- For i As Integer = 0 To handlerParams.Length - 1
- dynamicParamTypes(i + 1) = handlerParams(i).ParameterType
- Next
- Dim dynamicHandler As New DynamicMethod("", Nothing, dynamicParamTypes)
- Dim eventIL As ILGenerator = dynamicHandler.GetILGenerator()
- 'load the parameters or everything will just BAM :)
- Dim local As LocalBuilder = eventIL.DeclareLocal(GetType(Object()))
- eventIL.Emit(OpCodes.Ldc_I4, handlerParams.Length + 1)
- eventIL.Emit(OpCodes.Newarr, GetType(Object))
- eventIL.Emit(OpCodes.Stloc, local)
- 'start from 1 because the first item is the instance. Load up all the arguments
- For i As Integer = 1 To handlerParams.Length
- eventIL.Emit(OpCodes.Ldloc, local)
- eventIL.Emit(OpCodes.Ldc_I4, i)
- eventIL.Emit(OpCodes.Ldarg, i)
- eventIL.Emit(OpCodes.Stelem_Ref)
- Next
- eventIL.Emit(OpCodes.Ldloc, local)
- 'Load as first argument the instance of the object for the methodToInvoke i.e methodInvoker
- eventIL.Emit(OpCodes.Ldarg_0)
- 'Now that we have it all set up call the actual method that we want to call for the binding
- eventIL.Emit(OpCodes.[Call], method)
- 'return
- eventIL.Emit(OpCodes.Pop)
- eventIL.Emit(OpCodes.Ret)
- 'create a delegate from the dynamic method
- Return dynamicHandler.CreateDelegate(eventHandlerType, methodOwner)
- End Function
Ich hätte nun gerne eine Verbesserung, dass man einen richtigen EventHandler angeben kann, entweder auch in Form eines MethodInfos, aber mw. auch gerne als Delegat.
Sinn der Sache ist für Wpf - damit könnte ich einen Event-Umleiter basteln, der Events vom View ins Viewmodel leitet - das geht nämlich derzeit in Wpf nicht.
Es gibt bereits derlei Lösungen, aber dazu müsste ich extra eine WpfToolkit-Dll mitliefern, und die ist auch nicht so komfortabel und performant wie das Teil, an dem ich grad sitze.
Also mein Problem ist "einfach" zeile#36, wo das MethodInfo aufgerufen wird.
Wie wäre das zu gestalten, wenn das MethodInfo nicht eine leere Action beschreibt, sondern etwa eine Action(Of MouseEventArgs), oder gleich die ganze MouseEventHandler-Signatur?
Und das eben flexibel, also dassich auch einen KeyDownEventhandler angeben kann, und der ruft mit den richtigen Parametern auf?
Wenn sich jmd. da reinknien mag - ich kann auch eine TestSolution aufsetzen, mit der bisherigen Funktionalität, und auch der neuen Funktionalität, unter Auslassung dieses fehlenden Details.
Falls gewünscht - die TestSolution in Wpf oder in Winforms?