如何使 ShowDialog() 不阻止调用者的事件
How can I make ShowDialog() not to block the caller's event
我的程序有点问题。我一直在 VS2005 VB.Net 中的设备应用程序中工作。该程序将 运行 在我的设备上,它将连接到蓝牙设备。这是当前代码:
在处理事件的class中:
Public Class BluetoothDevice : Implements IRFID
'static instance of class
Public Shared _btDevice as BluetoothDevice
Private WithEvents bluetoothDevice as BRIReader
'This is the event handler
Private Sub BluetoothDevice_EventHandlerConnectionStateChanged(ByVal sender as Object, ByVal EvtArgs As EVTADV_DeviceConnectionStateEventArgs) handles bluetoothDevice.EventHandlerDeviceConnectState
Select Case EvtArgs.DeviceConnectState
Case EVTADV_DeviceConnectionStateEventArgs.CONNECTED
RaiseEvent OnReaderConnectionEventChanged(connectionState.Connected)
Case EVTADV_DeviceConnectionStateEventArgs.OFFLINE
RaiseEvent OnReaderConnectionEventChanged(connectionState.Offline)
Case EVTADV_DeviceConnectionStateEventArgs.RECONNECTING
RaiseEvent OnReaderConnectionEventChanged(connectionState.Reconnecting)
End Select
End Sub
End Class
在 UI 捕捉 RaiseEvent 的表单中。这也是主要形式:
Private Delegate Sub xOnReaderConnectEventChangeHandler(ByVal connState as connectionState)
Private Sub OnReaderConnectEventChangeHandler(ByVal connState as connectionState)
If Me.InvokeRequired Then
Me.Invoke(New xOnReaderConnectEventChangeHandler(AddressOf OnReaderConnectEventChangeHandler), connState)
Else
Select Case connState
Case connectionState.Connected
'_form here is a global object containing the form we ShowDialog()
If _form IsNot Nothing
_form.Dispose()
_form = Nothing
EndIf
Case connectionState.Offline
'haven't done anything yet
Case connectionState.Reconnecting
'show the form
_form.ShowDialog()
End Select
End If
End Sub
下面是将尝试重新连接设备的表单。这是计算自重新连接状态以来经过的时间的表格,并且有一个 "Cancel" 按钮:
Public Class FormReconnect
Private WithEvents _irfid as IRFID
Private Sub FormReconnect_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'form load
'this method returns the instance of BluetoothDevice Class
_irfid = BluetoothDevice.GetInstance()
End Sub
'I also handle the event here since the caller form is not active
'This form SHOULD close when the connection is established
Private Delegate Sub xOnReaderConnectionEventChangeHandler(ByVal connState As connectionState)
Private Sub OnReaderConnectionEventChangeHandler(ByVal connState As connectionState) Handles _irfid.OnReaderConnectionEventChange
If Me.InvokeRequired Then
Me.Invoke(New xOnReaderConnectionEventChangeHandler(AddressOf OnReaderConnectionEventChangeHandler), connState)
Else
Select Case connState
Case connState.Connected
'I only handle the connected state. If Device is connected, close this form
Me.Close()
End Select
End If
End Sub
End Class
情况是,当主窗体出现时,我把设备的电池拔掉,它们的连接状态会变成离线状态,然后立即重新连接,然后重新连接窗体就会出现。问题是,当通过 ShowDialog()
方法激活表单重新连接时,处理事件 (BluetoothDevice
) 的 Class 将不会被触发,即使设备连接状态已经是 Connected
(在设备中以闪烁的灯显示)。似乎表单重新连接的 ShowDialog()
阻塞了 class,因为当我按下取消按钮并且表单重新连接关闭时,BluetoothDevice
的事件处理程序将被触发。这里最好的解决方法是什么?我试过Show()
,它触发了事件,但它是由调用者和表单重新连接处理的,使表单重新连接关闭,而不显示主表单。
编辑 1: 我想要做的是,当我 ShowDialog()
并且表单重新连接处于活动状态时(因此,表单主是 "hidden"在 Reconnect 下),Form Reconnect 将处理 BluetoothDevice
Class.
中引发的事件
编辑 2: 当表单重新连接处于活动状态时。 BluetoothDevice
不引发任何事件。认为它被 ShowDialog()
阻止了。因此,即使连接状态为 "Connected".
,Form Reconnect 也不会关闭
使用这个方法。
- 主窗体(使用单例模式)处理与设备相关的所有事件
在断开连接时,或在开始时创建一个 线程 并在那里放置显示重新连接表单(同样对此表单使用单例模式)逻辑。
MainForm.getInstance.Invoke(新方法调用者(子()
Dim formReconnect As Form = formReconnect.GetInstance()
如果 formReconnect.visible = False 那么
formReconnect.TopMost = 真
formReconnect.Show()
结束如果
结束子))
通过重新连接重新连接后window 调用主窗体并关闭重新连接窗体
- 如果设备自动重新连接让主窗体在重新连接窗体上调用关闭方法。
在触发Form Reconnect时使用了BeginInvoke
,这样Form Reconnect就可以处理Event了。我只需要 RemoveHandler Form Main 以防止它引发相同的事件。
我的程序有点问题。我一直在 VS2005 VB.Net 中的设备应用程序中工作。该程序将 运行 在我的设备上,它将连接到蓝牙设备。这是当前代码:
在处理事件的class中:
Public Class BluetoothDevice : Implements IRFID
'static instance of class
Public Shared _btDevice as BluetoothDevice
Private WithEvents bluetoothDevice as BRIReader
'This is the event handler
Private Sub BluetoothDevice_EventHandlerConnectionStateChanged(ByVal sender as Object, ByVal EvtArgs As EVTADV_DeviceConnectionStateEventArgs) handles bluetoothDevice.EventHandlerDeviceConnectState
Select Case EvtArgs.DeviceConnectState
Case EVTADV_DeviceConnectionStateEventArgs.CONNECTED
RaiseEvent OnReaderConnectionEventChanged(connectionState.Connected)
Case EVTADV_DeviceConnectionStateEventArgs.OFFLINE
RaiseEvent OnReaderConnectionEventChanged(connectionState.Offline)
Case EVTADV_DeviceConnectionStateEventArgs.RECONNECTING
RaiseEvent OnReaderConnectionEventChanged(connectionState.Reconnecting)
End Select
End Sub
End Class
在 UI 捕捉 RaiseEvent 的表单中。这也是主要形式:
Private Delegate Sub xOnReaderConnectEventChangeHandler(ByVal connState as connectionState)
Private Sub OnReaderConnectEventChangeHandler(ByVal connState as connectionState)
If Me.InvokeRequired Then
Me.Invoke(New xOnReaderConnectEventChangeHandler(AddressOf OnReaderConnectEventChangeHandler), connState)
Else
Select Case connState
Case connectionState.Connected
'_form here is a global object containing the form we ShowDialog()
If _form IsNot Nothing
_form.Dispose()
_form = Nothing
EndIf
Case connectionState.Offline
'haven't done anything yet
Case connectionState.Reconnecting
'show the form
_form.ShowDialog()
End Select
End If
End Sub
下面是将尝试重新连接设备的表单。这是计算自重新连接状态以来经过的时间的表格,并且有一个 "Cancel" 按钮:
Public Class FormReconnect
Private WithEvents _irfid as IRFID
Private Sub FormReconnect_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'form load
'this method returns the instance of BluetoothDevice Class
_irfid = BluetoothDevice.GetInstance()
End Sub
'I also handle the event here since the caller form is not active
'This form SHOULD close when the connection is established
Private Delegate Sub xOnReaderConnectionEventChangeHandler(ByVal connState As connectionState)
Private Sub OnReaderConnectionEventChangeHandler(ByVal connState As connectionState) Handles _irfid.OnReaderConnectionEventChange
If Me.InvokeRequired Then
Me.Invoke(New xOnReaderConnectionEventChangeHandler(AddressOf OnReaderConnectionEventChangeHandler), connState)
Else
Select Case connState
Case connState.Connected
'I only handle the connected state. If Device is connected, close this form
Me.Close()
End Select
End If
End Sub
End Class
情况是,当主窗体出现时,我把设备的电池拔掉,它们的连接状态会变成离线状态,然后立即重新连接,然后重新连接窗体就会出现。问题是,当通过 ShowDialog()
方法激活表单重新连接时,处理事件 (BluetoothDevice
) 的 Class 将不会被触发,即使设备连接状态已经是 Connected
(在设备中以闪烁的灯显示)。似乎表单重新连接的 ShowDialog()
阻塞了 class,因为当我按下取消按钮并且表单重新连接关闭时,BluetoothDevice
的事件处理程序将被触发。这里最好的解决方法是什么?我试过Show()
,它触发了事件,但它是由调用者和表单重新连接处理的,使表单重新连接关闭,而不显示主表单。
编辑 1: 我想要做的是,当我 ShowDialog()
并且表单重新连接处于活动状态时(因此,表单主是 "hidden"在 Reconnect 下),Form Reconnect 将处理 BluetoothDevice
Class.
编辑 2: 当表单重新连接处于活动状态时。 BluetoothDevice
不引发任何事件。认为它被 ShowDialog()
阻止了。因此,即使连接状态为 "Connected".
使用这个方法。
- 主窗体(使用单例模式)处理与设备相关的所有事件
在断开连接时,或在开始时创建一个 线程 并在那里放置显示重新连接表单(同样对此表单使用单例模式)逻辑。
MainForm.getInstance.Invoke(新方法调用者(子() Dim formReconnect As Form = formReconnect.GetInstance() 如果 formReconnect.visible = False 那么 formReconnect.TopMost = 真 formReconnect.Show() 结束如果
结束子))通过重新连接重新连接后window 调用主窗体并关闭重新连接窗体
- 如果设备自动重新连接让主窗体在重新连接窗体上调用关闭方法。
在触发Form Reconnect时使用了BeginInvoke
,这样Form Reconnect就可以处理Event了。我只需要 RemoveHandler Form Main 以防止它引发相同的事件。