[英]vb.net dll reflection event
我试图将用户定义的事件参数类从dll传递到我的主程序。 两者都定义了事件参数类,但是当我尝试将事件委托绑定到方法时,由于其签名不兼容,因此不会绑定。 我已将代码简化为主要问题。
dll中的代码引发一个名为ValueChange的事件,并以ValueEventArgs作为参数:
Public Class Main
Public Event ValueChange(ByVal sender As System.Object, ByVal e As ValueEventArgs)
Private _Value As Integer
Public Sub Up()
_Value += 1
RaiseEvent ValueChange(Me, New ValueEventArgs(_Value))
End Sub
End Class
Public Class ValueEventArgs
Inherits System.EventArgs
Public Property Value As Integer
Public Sub New(ByVal Value As Integer)
Me.Value = Value
End Sub
End Class
主程序加载dll并将事件委托绑定到方法ShowValue:
Imports System.Reflection
Public Class Main
Private DriverAssembly As [Assembly]
Private DriverClass As Type
Private DriverClassInstance As Object
Private Sub ButtonLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonLoad.Click
DriverAssembly = [Assembly].Load("reflection_event, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
DriverClass = DriverAssembly.GetType("ReflectionEventDll.Main")
DriverClassInstance = Activator.CreateInstance(DriverClass)
' get the handler method
Dim Method As MethodInfo = Me.GetType.GetMethod("ShowValue")
' get the event and create a delegate
Dim ValueChangeEvent As EventInfo = DriverClass.GetEvent("ValueChange")
Dim Handler As [Delegate] = [Delegate].CreateDelegate(ValueChangeEvent.EventHandlerType, Me, Method) ' Fails
' Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
' add the event handler
ValueChangeEvent.AddEventHandler(DriverClassInstance, Handler)
End Sub
Private Sub ButtonUp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonUp.Click
DriverClass.GetMethod("Up").Invoke(DriverClassInstance, Nothing) ' invoke the method on the driver class instance
End Sub
Public Sub ShowValue(ByVal sender As Object, ByVal e As ValueEventArgs)
MessageBox.Show(e.Value.ToString())
End Sub
End Class
Public Class ValueEventArgs
Inherits System.EventArgs
Public Property Value As Integer
Public Sub New(ByVal Value As Integer)
Me.Value = Value
End Sub
End Class
如果我删除了委托和AddEventHandler的创建,那么一切都会正常进行,当然不会发生任何事件。
有趣的是,如果我在主程序中更改ShowValue方法的参数,则所有事件(包括事件)都会突然起作用。
Public Sub ShowValue(ByVal sender As Object, ByVal e As EventArgs)
' works, but the Value is lost
End Sub
它会变得更好,因为它不会完全丢失。 如果在Sub上放置一个断点,我可以看到e包含一个名为Value的属性。
DirectCast也会失败,但是将EventArgs写入对象似乎可行。
Public Sub ShowValue(ByVal sender As Object, ByVal e As EventArgs)
Dim Obj As Object = e
MessageBox.Show(Obj.Value.ToString())
End Sub
它有效,但是我认为这不是正确的方法。 从dll处理事件时,如何使用用户定义的事件参数类?
借助此答案,我已经找到了解决方案。 我觉得这是目前最好的解决方案,如果失败,它会产生可用的错误。
dll中的代码和方法的绑定保持不变,但是被调用的方法现在使用反射来获取Value属性。 移植到VB.net的方法如下:
Public Sub ShowValue(ByVal sender As Object, ByVal e As EventArgs)
Dim ValueProperty As PropertyInfo = e.GetType().GetProperty("Value")
Dim Value As Integer = Convert.ToInt32(ValueProperty.GetValue(e, Nothing))
MessageBox.Show(Value.ToString())
End Sub
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.