更新:我认为这事做的窗口句柄的MainForm的延迟实例-但一直没能制定出相当如何将导致这里看到的行为。
通过第三方COM接口的应用程序请求数据提供一个回调来处理结果。 在回调中,UI需要更新 - 但预期更新不起作用。 这是因为如果MainForm中的值复制已经建立,当MainForm.DataReady
被调用或直接调用跨线程,但UI更新工作从事件处理程序执行时预期。 你能解释一下为什么吗?
(注: AppDomain.CurrentDomain.Id
总是1
中的MainForm或ClassB的是否检查。)
初始代码 -从ClassB的实例调用到DataReady而不的MainForm InvokeRequred /代表/调用逻辑。 应用程序UI变化按预期工作,MainForm中SomeListControl.EmptyListMsg = "Not Available"
改变不会“大棒”(仿佛适用于MainForm的一个单独的副本)
Module AppGlobals
Public WithEvents A As ClassA
End Module
Partial Friend Class MyApplication
Private Sub MyApplication_Startup(ByVal sender As Object,
ByVal e As StartupEventArgs) Handles Me.Startup
A = New ClassA()
End Sub
End Class
Class MainForm
private sub getData
ToggleWait(True)
SomeListControl.Clear()
A.getData() 'Sets up the com object & callback
end sub
Public Sub DataReady()
ToggleWait(False)
' Do something with the data
End Sub
Private Sub ToggleWait(toggle as Boolean)
Application.UseWaitCursor = False
if toggle then
SomeListControl.EmptyListMsg = "Not Available"
else
SomeListControl.EmptyListMsg = "Please Wait"
end if
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
sub getdata_callback(results() as Object) handles IComObjectClient.getdata_callback
' Get the results
MainForm.DataReady()
end sub
End Class
新增InvokeRequred逻辑DataReady,还是直接从ClassB的调用 。 InvokeRequired是不正确的,应用程序UI变化按预期工作,MainForm中SomeListControl.EmptyListMsg = "Not Available"
改变不会“大棒”(仿佛适用于MainForm的一个单独的副本)
Class MainForm
Public Delegate Sub DataReadyDelegate(ByVal toggle As Boolean)
...
Public Sub DataReady()
If InvokeRequired Then
Invoke(New DataReadyDelegate()
Else
ToggleWait(False)
' Do something with the data
End If
End Sub
...
End Class
调用MainForm.DataReady
直接从ClassB的了异常:“调用或BeginInvoke可直到窗口句柄已创建不能在一个控件调用。” 直到我强迫的窗口句柄创建。 然后,它的相同的行为之前,即InvokeRequired是不正确的,应用程序UI变化按预期工作,MainForm中SomeListControl.EmptyListMsg = "Not Available"
改变不会“大棒”(仿佛适用于MainForm的一个单独的副本)
Class ClassB
Implements IComObjectClient
Public Delegate Sub DataReadDelegate()
sub getdata_callback(results() as Object) handles IComObjectClient.getdata_callback
' Get the results
If Not MainForm.IsHandleCreated Then
' This call forces creation of the control's handle
Dim handle As IntPtr = MainForm.Handle
End If
MainForm.Invoke(New DataReadyDelegate(AddressOf MainForm.DataReady))
end sub
End Class
从事件处理程序定义的自定义执行 “得到的数据”在ClassA和ClassB的事件。 ClassA的监听ClassB.got_data_event,提高ClassA.got_data_event,MainForm的监听ClassA.got_data_event并通过调用DataReady处理它()。 此工程 - InvokeRequired为真,则调用excuted,应用程序UI和预期的MainForm UI变化的工作。
Class MainForm
Public Delegate Sub DataReadyDelegate()
...
Public Sub DataReady()
If InvokeRequired Then
Invoke(New DataReadyDelegate()
Else
ToggleWait(False)
' Do something with the data
End If
End Sub
Public Sub _GotData_HandleEvent(ByVal resultMessage As String)
DataReady()
End Sub
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles Me.Load
...
ToggleWait(False)
AddHandler A.GotData, AddressOf _GotData_HandleEvent
...
End Sub
...
End Class