2

主窗体是否有某种方法可以在不参考引发事件的 ClassB 的特定实例的情况下侦听 ClassB 的自定义事件的任何引发?

将生成事件的 ClassB 实例当前在表单知道的 ClassA 实例中匿名实例化。

(最终更新:我对 MainForm 方法的直接调用没有按预期工作的原因是这个问题的已接受答案。)

更新我怀疑它比我想象的要复杂。以下引用解释了为什么我对 MainForm.DataReady() 的调用不起作用 - 以一种令人发狂的晦涩方式。

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

Cross AppDomain MarshallByRef vs value copy 讨论

更新2:

使用:

Debug.WriteLine("SetWaitState executing with Id={0}", AppDomain.CurrentDomain.Id)

在本地事件处理程序MainForm.DataReady()的上下文中执行并从显示它们每次都在相同的情况下运行。这使得不同的线程成为问题的原因——但在每种情况下都返回 false。它仍然没有意义 - 但至少自定义事件 - 根据需要冒泡 - 确实有效。MainFormClassBAppDomainMainForm.InvokeRequired

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


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
4

2 回答 2

1

或者一起忽略代表,只在 A 类中捕获 B 类事件,并引发一个新的 A 类事件,您的主子也可以连接...

就像是...

    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
于 2013-01-03T23:47:21.623 回答
0

主窗体是否有某种方法可以在不参考引发事件的 ClassB 的特定实例的情况下侦听 ClassB 的自定义事件的任何引发?

你可以,但你必须这样做

  1. 声明一个公共的 CustomEventHandler 委托
  2. 声明一个 ClassB 变量,以便您可以添加处理程序
  3. 将处理程序从 MainFrom 传递到 A 类

例如

Public Class MainForm

    Private Sub _ClassB_HandleEvent(ByVal ResultMessage As String)
      'do something with the Message
    End Sub

    Private A As New ClassA

    Public Sub getData()

        Dim eh As New ClassB.CustomEventHandler(AddressOf _ClassB_HandleEvent) 'create the delegate
        A.getData(eh) 'Pass it to ClassA
    End Sub
End Class


Public Class ClassA

    Public Sub getData(ByVal eh As ClassB.CustomEventHandler)
        Dim b As New ClassB
        AddHandler b.CustomEvent, eh
        Call setClient(b)
    End Sub

    Public Sub setClient(ByVal b As ClassB)
        b.getdata_callback()
    End Sub

End Class

Public Class ClassB
    Delegate Sub CustomEventHandler(ByVal ResultMessage As String) 'Declare the handler
    Public Event CustomEvent As CustomEventHandler

    Sub getdata_callback()
        RaiseEvent CustomEvent("Got Data")
    End Sub

End Class
于 2013-01-03T23:21:43.523 回答