Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. .NET (Core and Framework)
  4. [VB.NET 2008] How to write in a textbox from another thread

[VB.NET 2008] How to write in a textbox from another thread

Scheduled Pinned Locked Moved .NET (Core and Framework)
tutorialcsharpcomhelp
7 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    steve_9496613
    wrote on last edited by
    #1

    Hi everybody, I have a simple project with a form and a class in another file to manage the COM port (from the article "Smart Device Print Engine for Compact Framework" by Orkun GEDiK). I open the COM port and I start its thread for receiving data. I want to write the received data in a textbox in the form. To do this, every byte I receive, I assign the value of this byte to a byte variable of the form called byt and I call from inside the loop of the thread a function in the form that stores all the bytes in a string dati (in hexadecimal format):

    Public Sub ScriviTesto2()
    Dim str As String

    If InvokeRequired Then
      Invoke(New Action(AddressOf ScriviTesto2))
      Return
    End If
    
    Try
      str = Hex(byt)
      dati &= str & " "
    Catch ex As Exception
      MessageBox.Show(ex.ToString)
    End Try
    

    End Sub

    This seems to work because if I run the code step by step I see that the string dati grows byte by byte and contains the correct values. When there are no more bytes to receive, always from inside the loop of the thread, I call another function of the form that should write my string in a text box:

    Public Sub ScriviTesto3()

    If InvokeRequired Then
      Invoke(New Action(AddressOf ScriviTesto3))
      Return
    End If
    
    TB1.Text &= dati & vbCrLf
    

    End Sub

    ...this function write nothing in the text box... why? The string data contains the right values, is not empty. I tried another way: I don't call the last funcion (ScriviTesto3()) but, when there are no more bytes to receive, I click a button of the form that do the same:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    TB1.Text &= dati & vbCrLf
    End Sub

    In this case, when I click the button the string dati is empty... I don't know why. I add the declaration of the involved variables:

    Public Class Form1
    Public byt As Byte
    Protected dati As String
    ...

    Can anyone help me? Thanks in advance.

    L 1 Reply Last reply
    0
    • S steve_9496613

      Hi everybody, I have a simple project with a form and a class in another file to manage the COM port (from the article "Smart Device Print Engine for Compact Framework" by Orkun GEDiK). I open the COM port and I start its thread for receiving data. I want to write the received data in a textbox in the form. To do this, every byte I receive, I assign the value of this byte to a byte variable of the form called byt and I call from inside the loop of the thread a function in the form that stores all the bytes in a string dati (in hexadecimal format):

      Public Sub ScriviTesto2()
      Dim str As String

      If InvokeRequired Then
        Invoke(New Action(AddressOf ScriviTesto2))
        Return
      End If
      
      Try
        str = Hex(byt)
        dati &= str & " "
      Catch ex As Exception
        MessageBox.Show(ex.ToString)
      End Try
      

      End Sub

      This seems to work because if I run the code step by step I see that the string dati grows byte by byte and contains the correct values. When there are no more bytes to receive, always from inside the loop of the thread, I call another function of the form that should write my string in a text box:

      Public Sub ScriviTesto3()

      If InvokeRequired Then
        Invoke(New Action(AddressOf ScriviTesto3))
        Return
      End If
      
      TB1.Text &= dati & vbCrLf
      

      End Sub

      ...this function write nothing in the text box... why? The string data contains the right values, is not empty. I tried another way: I don't call the last funcion (ScriviTesto3()) but, when there are no more bytes to receive, I click a button of the form that do the same:

      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      TB1.Text &= dati & vbCrLf
      End Sub

      In this case, when I click the button the string dati is empty... I don't know why. I add the declaration of the involved variables:

      Public Class Form1
      Public byt As Byte
      Protected dati As String
      ...

      Can anyone help me? Thanks in advance.

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      steve_9496613 wrote:

      I call another function of the form that should write my string in a text box:

      Pass the data to display there as a parameter.

      steve_9496613 wrote:

      In this case, when I click the button the string dati is empty... I don't know why.

      Access to the form's field isn't thread-safe. You could lock it in a property, but that slow down things nicely. Hence, I'd suggest to create a list of bytes on your receiver-thread, and to pass this as a paramater to the form, say, once a second.

      Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

      S 1 Reply Last reply
      0
      • L Lost User

        steve_9496613 wrote:

        I call another function of the form that should write my string in a text box:

        Pass the data to display there as a parameter.

        steve_9496613 wrote:

        In this case, when I click the button the string dati is empty... I don't know why.

        Access to the form's field isn't thread-safe. You could lock it in a property, but that slow down things nicely. Hence, I'd suggest to create a list of bytes on your receiver-thread, and to pass this as a paramater to the form, say, once a second.

        Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

        S Offline
        S Offline
        steve_9496613
        wrote on last edited by
        #3

        Thanks Eddy. I have modified the first function as you suggested to do for the second one:

        Public Sub ScriviTesto2(ByVal dato As Byte)
        Dim str As String

        If InvokeRequired Then
          Invoke(New Action(Of Byte)(AddressOf ScriviTesto2), dato)
          'Invoke(New Action(AddressOf ScriviTesto2))
          Return
        End If
        
        Try
          'str = Hex(byt)
          'dati &= str & " "
          str = Hex(dato)
          dati &= str & " "
          TB1.Text &= Hex(dato) & " "
          'TB1.Text = dati
        Catch ex As Exception
          MessageBox.Show(ex.ToString)
        End Try
        

        End Sub

        In the receiver thread I call this function every byte I receive, passing to it the byte just received. As before the string dati grows byte by byte so I can say that I correctly pass the parameter dato to this function but nothing is written in the text box TB1. Writing byte by byte in a textbox is not the fastest way but I just wanted to see if passing data as parameter to the function could be the solution. Perhaps the text box is not the right objet to use or, more likely, I'm missing something important. I did another try: as you suggested I created a byte array in the receiver thread, I fill it with the bytes received and at the end of data reception I call another function in form1 passing to it the byte array:

        Public Sub ScriviTesto4(ByVal datiIn As Byte())
        Dim i As Int32

        If InvokeRequired Then
          Invoke(New Action(Of Byte())(AddressOf ScriviTesto4))
          Return
        End If
        
        For i = 0 To (datiIn.Count - 1)
          TB1.Text &= Hex(datiIn(i)) & " "
        Next
        TB1.Text &= vbCrLf
        

        End Sub

        Running step by step in debug I see that the array datiIn contains the right bytes and also the TB1.Text contains the right values but I see nothing in the text box in the form! What I'm doing wrong?

        L 1 Reply Last reply
        0
        • S steve_9496613

          Thanks Eddy. I have modified the first function as you suggested to do for the second one:

          Public Sub ScriviTesto2(ByVal dato As Byte)
          Dim str As String

          If InvokeRequired Then
            Invoke(New Action(Of Byte)(AddressOf ScriviTesto2), dato)
            'Invoke(New Action(AddressOf ScriviTesto2))
            Return
          End If
          
          Try
            'str = Hex(byt)
            'dati &= str & " "
            str = Hex(dato)
            dati &= str & " "
            TB1.Text &= Hex(dato) & " "
            'TB1.Text = dati
          Catch ex As Exception
            MessageBox.Show(ex.ToString)
          End Try
          

          End Sub

          In the receiver thread I call this function every byte I receive, passing to it the byte just received. As before the string dati grows byte by byte so I can say that I correctly pass the parameter dato to this function but nothing is written in the text box TB1. Writing byte by byte in a textbox is not the fastest way but I just wanted to see if passing data as parameter to the function could be the solution. Perhaps the text box is not the right objet to use or, more likely, I'm missing something important. I did another try: as you suggested I created a byte array in the receiver thread, I fill it with the bytes received and at the end of data reception I call another function in form1 passing to it the byte array:

          Public Sub ScriviTesto4(ByVal datiIn As Byte())
          Dim i As Int32

          If InvokeRequired Then
            Invoke(New Action(Of Byte())(AddressOf ScriviTesto4))
            Return
          End If
          
          For i = 0 To (datiIn.Count - 1)
            TB1.Text &= Hex(datiIn(i)) & " "
          Next
          TB1.Text &= vbCrLf
          

          End Sub

          Running step by step in debug I see that the array datiIn contains the right bytes and also the TB1.Text contains the right values but I see nothing in the text box in the form! What I'm doing wrong?

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          steve_9496613 wrote:

          Perhaps the text box is not the right objet to use or, more likely, I'm missing something important.

          It's not optimal, but it should display some text. That's what it's there for.

          steve_9496613 wrote:

          Running step by step in debug I see that the array datiIn contains the right bytes and also the TB1.Text contains the right values but I see nothing in the text box in the form!

          Did you create the textbox on the mainthread?

          For i = 0 To (datiIn.Count - 1)
          string x = Hex(datiIn(i)) & " "
          TB1.Text = TB1.Text + x
          Next

          Can you write the string x to the debugger?

          Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

          S 1 Reply Last reply
          0
          • L Lost User

            steve_9496613 wrote:

            Perhaps the text box is not the right objet to use or, more likely, I'm missing something important.

            It's not optimal, but it should display some text. That's what it's there for.

            steve_9496613 wrote:

            Running step by step in debug I see that the array datiIn contains the right bytes and also the TB1.Text contains the right values but I see nothing in the text box in the form!

            Did you create the textbox on the mainthread?

            For i = 0 To (datiIn.Count - 1)
            string x = Hex(datiIn(i)) & " "
            TB1.Text = TB1.Text + x
            Next

            Can you write the string x to the debugger?

            Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

            S Offline
            S Offline
            steve_9496613
            wrote on last edited by
            #5

            Eddy Vluggen wrote:

            Did you create the textbox on the mainthread?

            I added the textbox to the form1 in the designer, it should be in the main thread. In form1 I declared an instance of the class to manage the COM:

            Dim NewCom As CommDev

            In the Load event of the form I create the new object:

            NewCom = New CommDev()

            In the New function of the class some parameters are set, like baud rate, parity, etc. When I open the COM port, I call an Init function that opens the COM port, sets buffer sizes, sets the device control block, sets timeouts, creates and starts the receiver thread.

            Eddy Vluggen wrote:

            Can you write the string x to the debugger?

            I used your code instead of mine and I can see the value of the string x, I mean that I can "add an expression control" (I don't know if this is the right translation of the italian "Aggiungi espressione di controllo" that appear in the right click menu over a variable during debug) to the string x and see its right value in the bottom windows of Visual Studio. Nothing appears in the textbox... I made also another try:

            Public Sub ScriviTesto4(ByVal datiIn As Byte())
            Dim i As Int32

            If InvokeRequired Then
              Invoke(New Action(Of Byte())(AddressOf ScriviTesto4))
              Return
            End If
            
            For i = 0 To (datiIn.Count - 1)
              TB1.Text &= Hex(datiIn(i)) & " "
            Next
            ScriviLabel(TB1.Text)  'write the textbox text to a label in the form
            TB1.Text &= vbCrLf
            

            End Sub

            Private Sub ScriviLabel(ByVal stringa As String)
            Label1.Text = stringa
            End Sub

            What I can see in the debug is that TB1.Text, stringa and Label1.Text all contains the right values but nothing appear in the window of my application. It seems to be a "visualization" problem, perhaps related to threads, but I'm not able to see the error.

            L 1 Reply Last reply
            0
            • S steve_9496613

              Eddy Vluggen wrote:

              Did you create the textbox on the mainthread?

              I added the textbox to the form1 in the designer, it should be in the main thread. In form1 I declared an instance of the class to manage the COM:

              Dim NewCom As CommDev

              In the Load event of the form I create the new object:

              NewCom = New CommDev()

              In the New function of the class some parameters are set, like baud rate, parity, etc. When I open the COM port, I call an Init function that opens the COM port, sets buffer sizes, sets the device control block, sets timeouts, creates and starts the receiver thread.

              Eddy Vluggen wrote:

              Can you write the string x to the debugger?

              I used your code instead of mine and I can see the value of the string x, I mean that I can "add an expression control" (I don't know if this is the right translation of the italian "Aggiungi espressione di controllo" that appear in the right click menu over a variable during debug) to the string x and see its right value in the bottom windows of Visual Studio. Nothing appears in the textbox... I made also another try:

              Public Sub ScriviTesto4(ByVal datiIn As Byte())
              Dim i As Int32

              If InvokeRequired Then
                Invoke(New Action(Of Byte())(AddressOf ScriviTesto4))
                Return
              End If
              
              For i = 0 To (datiIn.Count - 1)
                TB1.Text &= Hex(datiIn(i)) & " "
              Next
              ScriviLabel(TB1.Text)  'write the textbox text to a label in the form
              TB1.Text &= vbCrLf
              

              End Sub

              Private Sub ScriviLabel(ByVal stringa As String)
              Label1.Text = stringa
              End Sub

              What I can see in the debug is that TB1.Text, stringa and Label1.Text all contains the right values but nothing appear in the window of my application. It seems to be a "visualization" problem, perhaps related to threads, but I'm not able to see the error.

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              Can you add another label on the form?

              Private Sub ScriviLabel(ByVal stringa As String)
              Label1.Text = "Hello world"
              Label2.Text = stringa
              End Sub

              This is the point where I'd paranoidly check the colour of my font.

              Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

              S 1 Reply Last reply
              0
              • L Lost User

                Can you add another label on the form?

                Private Sub ScriviLabel(ByVal stringa As String)
                Label1.Text = "Hello world"
                Label2.Text = stringa
                End Sub

                This is the point where I'd paranoidly check the colour of my font.

                Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

                S Offline
                S Offline
                steve_9496613
                wrote on last edited by
                #7

                Hi Eddy, thanks for your efforts. I add the second label but no label takes the right content in the form; in the debug the Text properties contain my string and the "Hello world" string. I also call the Refresh method of labels and form but nothing changes. Before I did another project where I used the SerialPort object of .NET, everything was in the form1 and I used the DataReceived event of the COM to write in the textbox the received data, always using the Invoke method, and everything was OK. In this project I don't use the SerialPort object but the API in coredll.dll (CreateFileW, ReadFile, SetCommMask, etc.) because I need to catch different information from the COM port and all this is in a separate class/file. This is the main difference between the two projecs, in addition to the fact that one works and the other not... Sorry but I really don't know what is THE fundamental information I'm missing to solve this problem, if you have any questions, please feel free to ask.

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups