Search code examples
vb.netshowrfidshowdialog

How can I make ShowDialog() not to block the caller's event


just a little problem with my program. I have been working in a device application in VS2005 VB.Net. This program will run at my device, that will connect in a bluetooth device. This is the current code:

In the class that handles the event:

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

In UI Form that catches the RaiseEvent. This is also the Main Form:

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

Now here is the form that will try to reconnect the device. This is form that counts the elapsed time since reconnecting state, and has a "Cancel" button:

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

The situation is, when the mainform shows, then I remove the battery from the device, their connection state will become offline, then reconnect immediately, then the reconnect form will show. The problem is, when the form reconnect is active through ShowDialog() method, the Class that handles the event(BluetoothDevice) will not be triggered, even if the device connect state is already Connected(shown in the device with a blinking light). It seems that the Form reconnect's ShowDialog() is blocking the class, because when I press the cancel button, and the form reconnect is closed, BluetoothDevice's event handler will trigger. What will be the best workaround here? I've tried the Show(), it triggers the event, but it is handled by both caller and the form reconnect, making the form reconnect close, without showing the main form.

EDIT 1: What I want this to do is, when I ShowDialog() and the Form Reconnect is active (thus, Form Main is "hidden" under Reconnect), Form Reconnect will handle the event that is being raised in BluetoothDevice Class.

EDIT 2: When Form Reconnect is active. BluetoothDevice does not raise any event. Think it is being blocked by ShowDialog(). So, Form Reconnect does not close even the connection state is "Connected".


Solution

  • Use this method.

    1. Main form (Use the singleton pattern) handles all the event associated with the device
    2. Upon disconnection, or at the start create a thread and put the show reconnect form (again use singleton pattern for this form too) logic there.

      MainForm.getInstance.Invoke(New MethodInvoker(Sub() Dim formReconnect As Form = formReconnect.GetInstance() If formReconnect.visible = False Then formReconnect.TopMost = True formReconnect.Show() End If
      End Sub))

    3. Upon reconnecting via the reconnect window invoke the main form and close reconnect form

    4. If the device reconnect automatically have the main form invoke the close method on reconnect form.