vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Zippen wie die Profis!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Ein- und Umsteiger
Problem mit Aktualisierung einer Textbox bei seriellem Empfang 
Autor: Lupus52
Datum: 16.12.16 12:41

Hallo,

ich habe eine Klasse Form1 und eine Klasse Class_COM. 2 separate Dateien. Form1.vb und Class_COM.vb
Das ganze gehört zu einer Mess-Software.

Habe das ganze runtergebrochen bis auf Minimum und finde den Fehler nicht.

Unter "Form" habe ich eine Form mit Button "Senden" und eine Textbox für die Ausgabe.

Unter Class_Com habe ich 4 Subs bzw. Funktionen.

OpenCom
WriteCom
ReadCom
CloseCom

Nach dem Druck auf Senden wird ein Steuer-String für ein Gerät korrekt gesendet.
Die Antwort wird auch korrekt empfangen wie man an einer Debugausgabe unter Read_Com sieht.

Parallel zur Debugausgabe soll der String in Form1.Textbox2.Text landen. Macht er aber nicht. Es passiert schlicht gar nichts in der Anzeige der Textbox. Wobei aber das Event "Textchangend" dieser Textbox ausgelöst wird! D.h. die Box hat was bekommen.

Wenn ich dieselbe Ausgabezeile an beliebige andere Stellen im Programm plaziere geht es. Z.b. unter OpenCom. Dann schreibt es "open" in die Textbox.

Nur die empfangenen Daten bzw. ein Dummytext "123" kommt nicht zur Anzeige.

Ein Refresh oder Update der Textbox bringt auch nichts.

Mein Latein ist am Ende

Imports System.IO.Ports
Imports System.Threading
 
Public Class Class_COM
Public Shared _serialPort As SerialPort
 
Public Function OpenCom() As Boolean 
 
  _serialPort = New SerialPort()        
  _serialPort.PortName = "COM2"
  _serialPort.BaudRate = 115200
  _serialPort.Parity = 0
  _serialPort.DataBits = 8
  _serialPort.StopBits = 1
  _serialPort.RtsEnable = True
  _serialPort.DtrEnable = True
  _serialPort.Handshake = 0
  _serialPort.ReadTimeout = 500         
  _serialPort.WriteTimeout = 500
 
  AddHandler _serialPort.DataReceived, AddressOf DataReceivedHandler
 
        Try
            _serialPort.Open()
        Catch ex As Exception
            MsgBox("Comport " & Form1.Comport & " konnte nicht geöffnet werden")
            Return 0
        End Try
 
        If _serialPort.IsOpen Then
            Form1.TextBox2.Text = "open"
            Return True
        Else
            Return 0
        End If
 
End Function
 
    Public Sub WriteCom(message)
        _serialPort.WriteLine(message)
    End Sub
 
    Public Function CloseCom() As Boolean
        _serialPort.Close()
        Form1.TextBox2.Text = "closed"
    End Function
 
    Public Function comstatus() As Boolean
        Return _serialPort.IsOpen
    End Function
 
    Private Shared Sub DataReceivedHandler(sender As Object, e As _
      SerialDataReceivedEventArgs)
        Dim sp As SerialPort = CType(sender, SerialPort)
        Dim indata As String = sp.ReadExisting()
        Console.Write("RX: ")
        Console.WriteLine(indata)
        Form1.TextBox2.Text = "123"
    End Sub
 
End Class
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Problem mit Aktualisierung einer Textbox bei seriellem Empfang 
Autor: effeff
Datum: 16.12.16 13:43

Vielleicht solltest Du den DataReceivedHandler dann auch Public machen...

Wieso steht da was von Console drin? Du arbeitest doch mit Forms, oder?

EALA FREYA FRESENA

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Problem mit Aktualisierung einer Textbox bei seriellem Empfang 
Autor: Lupus52
Datum: 16.12.16 15:03

Hallo

>Vielleicht solltest Du den DataReceivedHandler dann auch Public machen...

Warum? Der Empfänger funktioniert doch. Die Routine ist ja nur lokal aktiv. Bzw. sie schreibt gezielt mit Form1.Textbox2.Text eben in die Textbox. Bzw. sie sollte es.

Sie schreibt auch offensichtlich was in Richtung Textbox. Das Textchanged-Ereignis der Box wird ausgelöst! Nur es erscheint kein Inhalt. Aber das schrieb ich schon.

Habe es auch mit Public versucht. Es ändert sich nichts.

>Wieso steht da was von Console drin? Du arbeitest doch mit Forms, oder?

Weil ich damit ins Ausgabefenster schreibe zwecks Debugging. Im Ausgabefenster erscheint mein empfangener Text. Aber das schrieb ich schon. UNd das hat auch nichts mit der Textbox zu tun.

Wenn ich Debug.write nehme erhalte ich keine Ausgabe im Ausgabefenster. Trotz gewählter Ausgabe "Debuggen". Also nehme ich Console. Da bin ich durch Zufall drauf gekommen. Keine Ahnung warum das so ist.


Frage: Ich finde hier keine Zitierfunktion. Gibt es die nicht wei in anderen Foren oder sehe ich sie bloß nicht?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Problem mit Aktualisierung einer Textbox bei seriellem Empfang 
Autor: sv00010
Datum: 16.12.16 17:42

Lupus52 schrieb:
Zitat:


Frage: Ich finde hier keine Zitierfunktion. Gibt es die nicht
wei in anderen Foren oder sehe ich sie bloß
nicht?

Zuerst auf Antworten klicken, dann kommt das Fenster zu schreiben und dann unten rechts neben dem Senden-Button, ist der Zitieren-Button.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Problem mit Aktualisierung einer Textbox bei seriellem Empfang 
Autor: Lupus52
Datum: 16.12.16 18:29

Hallo,

wenn ich das Antwortenfeld aufhabe, gibt es rechts unten nur nur "Senden" und "Vorschau"
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Problem mit Aktualisierung einer Textbox bei seriellem Empfang 
Autor: sv00010
Datum: 16.12.16 19:33

Lupus52 schrieb:
Zitat:

Hallo,

wenn ich das Antwortenfeld aufhabe, gibt es rechts unten nur
nur "Senden" und "Vorschau"

Du kannst auch den Text per copy & paste einfügen und am Anfang des zu zitierenden Text "quote" reinschreiben, mit [] herum und am Ende des zu zitierenden Textes "/quote" mit [] herum.
Ich kann das leider hier nicht richtig reinschreiben, weil das sonst als zitieren angezeigt wird.

https://www.bbcode.org/examples/?id=8
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Problem mit Aktualisierung einer Textbox bei seriellem Empfang 
Autor: Lupus52
Datum: 19.12.16 00:55

sv00010 schrieb:
Zitat:

Lupus52 schrieb:
Zitat:

Hallo,

wenn ich das Antwortenfeld aufhabe, gibt es rechts unten nur
nur "Senden" und
"Vorschau"

Du kannst auch den Text per copy & paste einfügen und am
Anfang des zu zitierenden Text "quote"
reinschreiben, mit [] herum und am Ende des zu zitierenden
Textes "/quote" mit [] herum.
Ich kann das leider hier nicht richtig reinschreiben, weil
das sonst als zitieren angezeigt wird.

https://www.bbcode.org/examples/?id=8


Danke - inzwischen bin ich hinter den "Forums-BUG" gekommen. Es gibt 2 Ansichtformen: Gesamtansicht und Threadansicht. Wenn ich bei der Gesamtansicht konkret bei einem Beitrag dazu auf "Antworten" klicke gibt es keinen Zitierbutton. Bei der Threadansicht gibt es ihn.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Problem mit Aktualisierung einer Textbox bei seriellem Empfang 
Autor: Manfred X
Datum: 19.12.16 06:20

Hallo!

Du greifst per "Form1" offenbar auf die Defaultinstanz des
Formulars zu. Allem Anschein nach ist das nicht die Instanz der
Form-Klasse, deren Textbox Du ansprechen möchtest.

Es gibt diverse Grundregeln im OOP.
Eine lautet sinngemäß, daß Klassen per Methodenaufruf mit untergeordneten
Klassen kommunizieren und die untergeordneten Klassen Ereignisse
verwenden, um Informationen zu liefern.
Man sollte NIE von außen auf Controls eines Formulars zugreifen.

Deine Com-Klasse sollte deshalb so oder ähnlich konstruiert werden:
Option Strict On : Option Explicit On
Imports System.IO.Ports
Imports System.Threading
 
Public Class Class_COM
    Private WithEvents _serialPort As SerialPort
 
    Public Event ComStateChanged(ByVal sender As Object, e As EventArgs)
    Public Event Datareceived(ByVal sender As Object, data As String)
 
    Public Function OpenCom(ByVal Comport As String) As Boolean
 
        _serialPort = New SerialPort
        _serialPort.PortName = "COM2"
        _serialPort.BaudRate = 115200
        _serialPort.Parity = 0
        _serialPort.DataBits = 8
        _serialPort.StopBits = StopBits.One
        _serialPort.RtsEnable = True
        _serialPort.DtrEnable = True
        _serialPort.Handshake = 0
        _serialPort.ReadTimeout = 500
        _serialPort.WriteTimeout = 500
 
 
        Try
            _serialPort.Open()
            If _serialPort.IsOpen Then
                RaiseEvent ComStateChanged(Me, EventArgs.Empty)
            End If
            Return _serialPort.IsOpen
        Catch ex As Exception
            Return False
        End Try
 
    End Function
 
    Public Function WriteCom(ByVal message As String) As Boolean
        Try
            _serialPort.WriteLine(message)
            Return True
        Catch
            Return False
        End Try
    End Function
 
    Public Function CloseCom() As Boolean
        Try
            _serialPort.Close()
            RaiseEvent ComStateChanged(Me, EventArgs.Empty)
            Return True
        Catch
            Return False
        End Try
    End Function
 
    Public Function comstatus() As Boolean
        Return _serialPort.IsOpen
    End Function
 
    Private Sub DataReceivedHandler(sender As Object, e As  _
      SerialDataReceivedEventArgs) Handles _serialPort.DataReceived
 
        Dim sp As SerialPort = CType(sender, SerialPort)
        Dim indata As String = sp.ReadExisting()
 
        RaiseEvent Datareceived(Me, indata)
    End Sub
 
End Class
Im Formular werden die Ereignisse verarbeitet. Etwa so ...
Public Class frmCom
 
    Dim WithEvents myCom As New Class_COM
 
    Dim WithEvents btnSenden As New Button _
        With {.Parent = Me, .Text = "Senden"}
 
    Dim txtState As New TextBox _
        With {.Parent = Me, .Top = 50}
    Dim txtData As New TextBox _
        With {.Parent = Me, .Top = 100}
 
    Private Sub frmCom_Load(sender As System.Object, _
        e As System.EventArgs) Handles MyBase.Load
 
        If Not myCom.OpenCom("xxxx") Then
            MsgBox("Port kann nicht geöffnet werden")
        End If
 
    End Sub
 
    Private Sub mycom_ComStateChanged(sender As Object, _
        e As System.EventArgs) Handles myCom.ComStateChanged
 
        txtState.Text = If(myCom.comstatus, "Open", "Close")
    End Sub
 
    Private Sub mycom_Datareceived(sender As Object, _
        data As String) Handles myCom.Datareceived
 
        txtData.Text = data
    End Sub
 
    Private Sub btnSenden_Click(sender As Object, _
        e As System.EventArgs) Handles btnSenden.Click
 
        myCom.WriteCom("XXX")
    End Sub
End Class
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Problem mit Aktualisierung einer Textbox bei seriellem Empfang 
Autor: Lupus52
Datum: 19.12.16 10:41

Manfred X schrieb:
Zitat:

Hallo!

Du greifst per "Form1" offenbar auf die
Defaultinstanz des
Formulars zu. Allem Anschein nach ist das nicht die Instanz
der
Form-Klasse, deren Textbox Du ansprechen möchtest.

Es gibt diverse Grundregeln im OOP.
Eine lautet sinngemäß, daß Klassen per Methodenaufruf mit
untergeordneten
Klassen kommunizieren und die untergeordneten Klassen
Ereignisse
verwenden, um Informationen zu liefern.
Man sollte NIE von außen auf Controls eines Formulars
zugreifen.



Morgen, danke für die Antwort. Bin gerade weiter am Experimentieren. Deine ganze Ausführung mag richtig sein und Schönheitstechnisch besser bzw. korrekter.

Aber eigentlich müsste mein Weg doch auch technisch korrekt sein?

Ich versuche mal so kurz wie möglioch zusammenzufassen:

Public Class Form1

enthält u.a. einen Open, Sende- und Closebutton und eine Textbox2

Public Class Class_COM

Enthält alles, was ich für die COM nutze.

(Stark abgespeckt)

    Public Shared _serialPort As SerialPort
 
    Public Function OpenCom() As Boolean                              ' 
    ' Schnittstelle öffnen
 
        _serialPort = New SerialPort()          
        _serialPort.PortName = "COM5"
        _serialPort.BaudRate = 115200
        _serialPort.Parity = 0
        _serialPort.DataBits = 8
        _serialPort.StopBits = 1
        _serialPort.RtsEnable = True
        _serialPort.DtrEnable = True
        _serialPort.Handshake = 0
        _serialPort.ReadTimeout = 500           
        _serialPort.WriteTimeout = 500
        _serialPort.Encoding = System.Text.Encoding.Default 'Standard ist  
        ' ASCII 7-Bit
 
        AddHandler _serialPort.DataReceived, AddressOf DataReceivedHandler
 
        Try
            _serialPort.Open()
        Catch ex As Exception
            MsgBox("Comport " & Form1.Comport & " konnte nicht geöffnet werden")
            Return False
        End Try
 
        If _serialPort.IsOpen Then
            Form1.TextBox2.Text = "open" 
            Return True
        Else
            Return False
        End If
 
    End Function
 
    Public Sub WriteCom(message)
        _serialPort.Write(message)
    End Sub
 
    Public Function CloseCom() As Boolean
        _serialPort.Close()
        Form1.TextBox2.Text = "closed"
        Return True
    End Function
 
    Public Shared Sub DataReceivedHandler(sender As Object, e As _
      SerialDataReceivedEventArgs)
        Dim sp As SerialPort = CType(sender, SerialPort)
        Dim indata As String = sp.ReadExisting()
 
        Console.Write("RXX: ")
        Console.WriteLine(indata)
 
        Form1.TextBox2.Text = indata 
 
    End Sub
 
End Class
Öffne ich von Form1 aus per Button die COM, erscheint die obige Message "open" erwartungsgemäß in der Textbox.

Dito bei Close. Klappt auch. Also ist die Interaktion der einen Klasse mit der Form1-Klasse möglich

Sende ich einen Text und er wird empfangen, dann wird das in der Debugausgabe gezeigt.

Dann soll er in die Textbox2 geschrieben werden.

   Private Sub TextBox2_TextChanged(sender As System.Object, e As _
     System.EventArgs) Handles TextBox2.TextChanged
        Dim h As String
        h = TextBox2.Text
    End Sub
Dort löst er das Ereignis "TextChanged" aus. Und der Text ist korrekt auslesbar. Als ist er angekommen.

Er steht in "h", wie man eindeutig sieht wenn man das Programm hier auf einen Breakpoint laufen lässt. Nur wird der nicht in der Box angezeigt. Da bleibt der letzte Text unverändert stehen.

Weder mit Refresh noch Update oder was sonst noch ich alles probiert habe.

Nochmal: 3 Funktionen aus der COM-Klasse senden Text. Bei 2en davon wird der Text von Form1 in der Textbox korrekt "upgedatet". Nur der empfangene Text aus der Empfangsfunktion kommt an, bleibt aber leer bzw. unsichtbar. Und löscht auch nicht den vorherigen Text an der Stelle in der Textbox2

Das ist das Phänomen, das ich nicht verstehe.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Problem mit Aktualisierung einer Textbox bei seriellem Empfang 
Autor: Lupus52
Datum: 19.12.16 13:24

Nachtrag: Habe deine Listings bezüglich der relevanten Zeilen eingebaut.

Dan bekam ich beim Versuch die Textbox zu beschreiben den Error.

"Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement TextBox2 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde."

Obwohl das ja im Thread Form1 steht. Aber ausgelöst eben durch den COM-Thread.

Weitere Forensuche brachte dann die Lösung per Invoke. Habe also das auch noch reingebastelt.

Erste Tests sind positiv! Jetzt muss ich mal mit echten Daten testen und nicht nur per Loop-Stecker.


Danke auf jeden Fall - ich bin einen riesigen Schritt weiter
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Problem mit Aktualisierung einer Textbox bei seriellem Empfang 
Autor: Manfred X
Datum: 19.12.16 19:44

Das ist korrekt.
Wenn die Com-Klasse in einem eigenen Thread ausgeführt wird,
kann der Zugriff auf Steuerelemente (sie laufen im UI-Thread)
nur per Invoke erfolgen.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Problem mit Aktualisierung einer Textbox bei seriellem Empfang 
Autor: Lupus52
Datum: 19.12.16 20:05

Ich danke dir - wenigstens dieser weitere Teil klappt jetzt auch. Es ist echt mühselig.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel