繁体   English   中英

vb.net dll反射事件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM