主窗体是否有某种方法可以监听ClassB的自定义事件的任何引发而不引用引发该事件的ClassB的特定实例?
生成事件的ClassB实例当前在表单知道的ClassA实例中匿名实例化。
(最终更新:我直接调用MainForm方法无效的原因在于我接受的答案to this question。)
更新我怀疑它比我想象的要复杂得多。以下引用解释了为什么我对MainForm.DataReady()的调用不起作用 - 以一种令人抓狂的模糊方式。
.NET事件的神奇之处在于,当您通过A的实例订阅B实例中的事件时,A会被发送到B的appdomain中。如果A不是MarshalByRef,则发送A的值副本。现在你有两个独立的A实例,这就是你遇到意外行为的原因。
Cross AppDomain MarshallByRef vs value copy discussion
UPDATE2:
使用:
Debug.WriteLine("SetWaitState executing with Id={0}", AppDomain.CurrentDomain.Id)
在MainForm.DataReady()
本地事件处理程序的上下文中执行MainForm
并且从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
答案 0 :(得分:1)
或者忽略所有代表,并且只捕获A类中的B类事件,并提升您的Main Sub可以连接的新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
答案 1 :(得分:0)
主窗体是否有某种方法可以监听ClassB的自定义事件的任何引发而不引用引发该事件的ClassB的特定实例?
你可以,但你必须
e.g。
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