.net 自定义事件的类级而非实例级处理?

.net 自定义事件的类级而非实例级处理?,.net,vb.net,delegates,event-handling,com-interop,.net,Vb.net,Delegates,Event Handling,Com Interop,主窗体是否有某种方法来侦听ClassB自定义事件的任何提升,而不引用引发该事件的ClassB的特定实例 将生成事件的ClassB实例当前在窗体知道的ClassA实例中匿名实例化 (最终更新:我对MainForm方法的直接调用没有像我预期的那样工作的原因在接受的答案中。) 更新我怀疑这比我想象的要复杂。下面的引文解释了为什么我对MainForm.DataReady()的调用无法正常工作——以一种令人发狂的模糊方式 NET事件的魔力隐藏了这样一个事实:当您通过A实例订阅B实例中的事件时,A会被发送到

主窗体是否有某种方法来侦听ClassB自定义事件的任何提升,而不引用引发该事件的ClassB的特定实例

将生成事件的ClassB实例当前在窗体知道的ClassA实例中匿名实例化

(最终更新:我对MainForm方法的直接调用没有像我预期的那样工作的原因在接受的答案中。)

更新我怀疑这比我想象的要复杂。下面的引文解释了为什么我对MainForm.DataReady()的调用无法正常工作——以一种令人发狂的模糊方式

NET事件的魔力隐藏了这样一个事实:当您通过A实例订阅B实例中的事件时,A会被发送到B的appdomain。如果A不是MarshalByRef,则发送A的值副本。现在您已经有了两个单独的实例,这就是为什么您会遇到意外行为

更新2:

使用:

Debug.WriteLine(“使用Id={0}执行的SetWaitState”,AppDomain.CurrentDomain.Id)

MainForm
本地事件处理程序的上下文中执行
MainForm.DataReady()
以及从
ClassB
调用时,显示它们每次都在相同的
AppDomain
中运行。这就留下了不同的线程作为问题的原因,但在每种情况下,
MainForm.InvokeRequired
都返回false。这仍然没有意义——但至少自定义事件——在必要时冒泡——确实起了作用

下面的代码说明了这些关系


Class MainForm
  private A as New ClassA

  private sub getData
    A.getData() 'Sets up the com object & callback
  end sub

  Private Sub _ClassB_HandleEvent(ResultMessage As String) Handles {some static/shared reference to ClassB}.CustomEvent
     'do something with the Message
  End Sub

End Class

Class ClassA

  public sub getData()
     Dim ComObj as New ComObject
     Call ComObj.setClient(New ClassB)
  End Sub

End Class

Class ClassB
  Implements IComObjectClient
  Public Event CustomEvent(ByVal ResultMessage As String)

  sub getdata_callback(results() as Object) handles IComObjectClient.getdata_callback
    ' Get the results
    RaiseEvent CustomEvent("Got Data") 'because calling MainForm.DataReady() doesn't work 
  end sub

End Class

主窗体是否有某种方法来侦听ClassB自定义事件的任何提升,而不引用引发该事件的ClassB的特定实例

你可以,但你必须

  • 声明公共CustomEventHandler委托
  • 声明ClassB变量,以便添加处理程序
  • 将处理程序从MainFrom传递到类a
  • e、 g


    或者忽略所有的代理,只需捕获A类中的B类事件,并引发一个新的A类事件,您的主Sub也可以连接该事件

    类似于

        Class MainForm
            private A As ClassA
    
            Public Sub _ClassB_HandleEvent(ByVal ResultMessage As String)
                ' Do Something like.... TextBox1.Text &= ("Received Event Saying - " & ResultMessage) & vbCrLf
            End Sub
    
            Private Sub GetData()
                A = New ClassA
                AddHandler A.GotDataFromClassB, AddressOf _ClassB_HandleEvent
                A.GetData()
            End Sub
        End Class
    
        Public Class ClassA
            Public Event GotDataFromClassB(ByVal ResultMessage As String)
            Private B As ClassB
    
            Public Sub GetData()
                B = New ClassB
                AddHandler B.CustomEvent, Sub(ResultMessage As String)
                                                    RaiseEvent GotDataFromClassB(ResultMessage)
                                          End Sub
                Dim ComObj as New ComObject
                Call ComObj.setClient(B)
            End Sub
        End Class
    
    Class ClassB
      Implements IComObjectClient
      Public Event CustomEvent(ByVal ResultMessage As String)
    
      sub getdata_callback(results() as Object) handles IComObjectClient.getdata_callback
        ' Get the results
        RaiseEvent CustomEvent("Got Data")
      end sub
    End Class
    

    那是不可能的。事件是由对象而不是类引发的。您可以为所有对象提供相同的事件处理程序,使用AddHandler+AddressOf关键字。但这通常会导致流泪,因为COM事件不需要传递任何类似于sender参数的内容。这是有效的@康拉德·弗里克斯(conrad frix)的解决方案可能同样好,但这是我决定采用的方案。很明显,跨应用程序域事件没有发生。非常好。。。很高兴我能帮忙!
        Class MainForm
            private A As ClassA
    
            Public Sub _ClassB_HandleEvent(ByVal ResultMessage As String)
                ' Do Something like.... TextBox1.Text &= ("Received Event Saying - " & ResultMessage) & vbCrLf
            End Sub
    
            Private Sub GetData()
                A = New ClassA
                AddHandler A.GotDataFromClassB, AddressOf _ClassB_HandleEvent
                A.GetData()
            End Sub
        End Class
    
        Public Class ClassA
            Public Event GotDataFromClassB(ByVal ResultMessage As String)
            Private B As ClassB
    
            Public Sub GetData()
                B = New ClassB
                AddHandler B.CustomEvent, Sub(ResultMessage As String)
                                                    RaiseEvent GotDataFromClassB(ResultMessage)
                                          End Sub
                Dim ComObj as New ComObject
                Call ComObj.setClient(B)
            End Sub
        End Class
    
    Class ClassB
      Implements IComObjectClient
      Public Event CustomEvent(ByVal ResultMessage As String)
    
      sub getdata_callback(results() as Object) handles IComObjectClient.getdata_callback
        ' Get the results
        RaiseEvent CustomEvent("Got Data")
      end sub
    End Class