Champgoblem2
Champgoblem2

Reputation: 37

VB.net trying to access a UI element from seperate thread is not working

I have a rich text box in my main for that I want to write stuff to from different threads. I have tried to do this using invoking, but I can't seem to get it to work. If I try it with:

If InvokeRequired Then
    Dim Dgate As writeLogDelegate = New writeLogDelegate(AddressOf writeLog)
    BeginInvoke(Dgate, New Object() {Message})
Else
    RTB_Log.AppendText(Message)
End If

then InvokeRequired does not return true like it should and checking if the handle is created returns false, but on form load, if I get the value of IsHandleCreated, it returns true. My method for trying to invoke writing is like so:

Thread Class snippet:

Public Sub startClientPoll(ByRef Sender As TcpListener)
    Dim TThread As New Thread(New ParameterizedThreadStart(AddressOf pollClientConnect))
    TThread.Start(Sender)
End Sub
Private Sub pollClientConnect(tcplistener As TcpListener)
    Do
        If tcplistener.Pending() Then
            'MessageBox.Show("")
            RaiseEvent clientConnecting()
        End If
    Loop Until Ended = True
End Sub

Event handler class snippet:

Private Sub client_Connect() Handles listenerSocket.clientConnecting
    Form1.writeLog("New client awaiting accept" & vbNewLine)
    Dim clientSocket As TcpClient = listenerSocket.AcceptTcpClient()
    Dim clientHandler As New MPClientReciever(clientSocket)
End Sub

Main form snippet:

Public Sub writeLog(ByVal Message As String)
    If Not IsHandleCreated Then
        CreateControl()
    End If
    If InvokeRequired Then
        Dim Dgate As writeLogDelegate = New writeLogDelegate(AddressOf writeLog)
        BeginInvoke(Dgate, New Object() {Message})
    Else
        RTB_Log.AppendText(Message)
    End If
End Sub

Upvotes: 0

Views: 130

Answers (1)

Ibrahim D.
Ibrahim D.

Reputation: 326

You can define a Sub globally on your class as the following:

Private Delegate Sub AddText_DL(ByVal txtControl As Control, ByVal txtVAL As String, ByVal append As Boolean)
Private Sub AddText(ByVal txtControl As Control, ByVal txtVAL As String, ByVal append As Boolean)
    If txtControl.InvokeRequired = True Then
        Dim progDel As New AddText_DL(AddressOf AddText)
        Dim parameters(2) As Object
        parameters(0) = txtControl
        parameters(1) = txtVAL
        parameters(2) = append
        txtControl.Invoke(progDel, parameters)
    Else
        If append = True Then
            txtControl.text &= txtVAL
        Else
            txtControl.text = txtVAL
        End If
    End If
End Sub

To use it in different threads, call

AddText(MyTextBoxObject, "add this text please, don't append", False)

And for your reference, if you want to access a UI control's property and get its set value, you can instead use:

Private Delegate Function CheckedStatus_DL(ByVal checkable As Control) As Boolean
Function CheckedStatus(ByVal checkable As Control) As Boolean
    If checkable.InvokeRequired = True Then
        Dim gridDel As New CheckedStatus_DL(AddressOf CheckedStatus)
        Dim parameters(0) As Object
        parameters(0) = checkable
        Return checkable.Invoke(gridDel, parameters)
    Else
        Return checkable.checked
    End If
End Function

Also you can use this Function with any control that has .Checked property

Upvotes: 2

Related Questions