none
Port com et textbox RRS feed

  • Discussion générale

  • Bonjour,

    j'ai du code VB.NET tout simple qui récupère des données sur un port com, qui traite la chaine et affiche le résultat dans un contrôle TextBox.

    Mon problème est que dès que l'évènement DataReceived est déclenché, le contrôle TextBox.text n'affiche pas ce que je lui demande d'afficher. L'évènement TextChanged du TextBox est bien déclenché à chaque fois que j'affecte quelque chose à la propriété Text du contrôle. Un MsgBox dans l'évènement TextChanged du contrôle affiche bien ce que je lui demande, mais dans le formulaire rien! J'avoue ne pas comprendre.

    Si quelqu'un peut m'aider merci d'avance.

    voici mon code:

    Imports System.IO.Ports
    
    Public Class Form1
        'Paramètres du port série
        Public Shared COMPort As String = "COM7"
        Private Const COM_BaudRate As Integer = 9600
        Private Const COM_Parity As System.IO.Ports.Parity = Parity.None
        Private Const COM_DataBits As Integer = 8
        Private Const COM_StopBits As System.IO.Ports.StopBits = StopBits.One
    
    
        Public Shared RFIDPort As SerialPort = Nothing
    
        Public Shared Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            Form1.OuvreCom()
    
            Form1.TextBox1.Text = "1" 's'affiche bien dans le controle texte
    
        End Sub
        Public Sub OuvreCom()
    
            RFIDPort = New SerialPort(COMPort, COM_BaudRate, COM_Parity, COM_DataBits, COM_StopBits)
            RFIDPort.ReadBufferSize = 20
            RFIDPort.ReadTimeout = 500
    
            AddHandler RFIDPort.DataReceived, AddressOf RFIDPort_DataReceived
    
            AddHandler RFIDPort.ErrorReceived, AddressOf RFIDPort_ErrorReceived
    
            RFIDPort.Open()
        End Sub
        Public Sub FermeCom()
            RemoveHandler RFIDPort.DataReceived, AddressOf RFIDPort_DataReceived
            RFIDPort.Close()
            RFIDPort.Dispose()
            RFIDPort = Nothing
        End Sub
        Public Shared Sub RFIDPort_ErrorReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialErrorReceivedEventArgs)
            RFIDPort.DiscardInBuffer()
            RFIDPort.DiscardOutBuffer()
            MsgBox("discard") 'juste pour savoir quand cet évenement se déclenche
        End Sub
        Public Shared Sub RFIDPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs)
            Threading.Thread.Sleep(500)
            Form1.TextBox1.Refresh()
            Application.DoEvents()
    
            Form1.TextBox1.Text = "2" 'ne s'afiche pas dans TextBox1.Text mais déclanche l'évenement onchanged du textbox
    
            Dim buf As String = CStr(RFIDPort.ReadExisting())
            MsgBox(buf & "   " & Len(buf))
            Form1.Affiche(Microsoft.VisualBasic.Right(buf, 17))
            RFIDPort.DiscardInBuffer() 'vide la mémoire du port en entrée
            buf = ""
    
            Application.DoEvents()
    
            Form1.FermeCom()
            Form1.OuvreCom()
            Form1.TextBox1.Select()
    
            Form1.TextBox1.Text = "5" 'ne s'afiche pas dans TextBox1.Text mais déclanche l'évenement onchanged du textbox
        End Sub
        Public Sub Affiche(ByVal Chaine As String)
            Dim i As Integer = 0
            Dim j As Integer = 0
            Dim Debut As Boolean = True
            Dim TChaine(Len(Chaine)) As String
    
            TextBox1.Text = "3" 'ne s'afiche pas dans TextBox1.Text mais déclanche l'évenement onchanged du textbox
    
            'Lecture et nettoyage de la chaine envoyée par le port com
            j = 1
            For i = 1 To Len(Chaine)
    
                If Asc(Mid(Chaine, i, 1)) = 3 Then
                    Exit For
                End If
                TChaine(j) = Asc(Mid(Chaine, i, 1))
                j = j + 1
                TChaine(0) = j
            Next
    
            'transformation de la chaine
            Dim Exa As String = ""
            For i = 1 To TChaine(0) - 1
                Exa = Exa & Chr(TChaine(i))
            Next
    
            Dim AvantCarte As String = ""
            For i = 1 To (TChaine(0) - 2) / 2 Step 2
                AvantCarte = AvantCarte & Chr(TChaine(TChaine(0) - (i + 1))) & Chr(TChaine(TChaine(0) - i))
            Next
    
            Dim carte As String = Convert.ToInt64(AvantCarte, 16)
            MsgBox(carte)
    
            TextBox1.Text = "4" 'ne s'afiche pas dans TextBox1.Text mais déclanche l'évenement onchanged du textbox
    
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            FermeCom()
            End
        End Sub
    
        Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
            MsgBox(Me.TextBox1.Text) 'affiche systématiquement la bonne valeur de textbox1.text
            Me.Refresh()
        End Sub
    
    End Class
    

    Voici les propriété du contrôle TextBox:

    D'avance merci pour votre aide.

    Fabienne


    Fab!

    jeudi 24 septembre 2015 13:00

Toutes les réponses

  • Bonjour, FabSaz,

    Est-ce que "2" (ou "5", "3" etc.) est confirmé comme contenu du TextBox1, si vous insérez des points d’arrêt juste après la ligne affectant la valeur au TextBox (et juste après les autres lignes correspondantes) ?

    Merci de nous tenir au courant.

    Cordialement,
    Dimitar

    vendredi 25 septembre 2015 12:51
    Modérateur
  • 
    

    Bonjour,

    merci pour votre réponse.

    Je ne comprend pas bien ce que vous voulez dire par "confirmé comme contenu". Ce qu'il se passe : Chaque affectation du textbox "1" ("2", "3"...) déclenche l'évènement "TextChange" du contrôle, mais seul le "1" est affiché dans celui ci.

    J'ai continué à chercher et j'ai trouvé que l'évènement DataReceived s'exécute dans un thread différent de l'appli, et ne peut donc accéder directement aux contrôles de celle ci. Il faut donc que je mette en place un Delegate pour passer mes données au formulaire.

    Je n'y arrive pas, j'ai l'erreur : "Impossible d'appeler Invoke ou BeginInvoke sur un contrôle tant que le handle de fenêtre n'a pas été créé"

    Pouvez vous m'aider?

    dans mes déclaration j'ai ça :

        Private Delegate Sub UdateFormDelegate()
        Private UpdateForm As UdateFormDelegate

    dans mon évènement j'ai ça :

            Form1.UpdateForm = New UdateFormDelegate(AddressOf ModifForm)
    
           
            Form1.buf = CStr(RFIDPort.ReadExisting())
            Form1.Invoke(Form1.UpdateForm)

    et voici ma procédure déléguée:

    Public Shared Sub ModifForm()
        Form1.TextBox1.Text = Form1.buf
    End Sub


    Fab!

    vendredi 25 septembre 2015 13:07
  • Bonjour, Fabienne,

    Le thread est-il toujours actuel?
    Je vous remercie par avance de votre retour.

    Cordialement,
    Teodora


    Votez! Appel à la contribution TechNet Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    vendredi 2 octobre 2015 14:53
    Modérateur