0

我正在从收发器将温度值读取到串行端口中,并且我希望该值更改我的 Visual Basic 表单中标签的值。这个值每隔几秒就会改变一次。我正在使用下面的代码:

Me.dataReceived.Text &= [text]

其中 dataReceived 是我正在使用的标签,[text] 是我从串口读取的数据。这会导致显示数据,但不是覆盖标签,而是一个接一个地写入值。(数据已附加)。我试图在 = 之前删除 & 但这没有用,因为什么也没出现。关于我能做什么的任何想法?

我正在使用的代码如下:

'To receive data into the text field
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived

    While (SerialPort1.IsOpen)
        ReceivedText(SerialPort1.ReadExisting())    'This is called automatically every time  data is received at the Serial Port
    End While

End Sub

Private Sub ReceivedText(ByVal [text] As String)

    Dim temperature As String

    'This function compares the creating Thread's ID with the calling Thread's ID
    If Me.dataReceived.InvokeRequired Then
        Dim x As New SetTextCallback(AddressOf ReceivedText)
        Me.Invoke(x, New Object() {(text)})
    Else
        'To output to the text box:
        Me.dataReceived.Text = text

        'To output to the label
        temperature = text
        Me.temp.Text = text
        hmd.Text = temperature

    End If
   End Sub
4

4 回答 4

5

如果要覆盖旧值,则不应使用&=而只是=分配新值:

Me.dataReceived.Text = newText

&=是相同的Me.dataReceived.Text = Me.dataReceived.Text & newText

来自MSDN

运算符将&=其右侧的 String 表达式连接到其左侧的 String 变量或属性,并将结果分配给其左侧的变量或属性。

于 2012-05-17T11:18:48.127 回答
1

试试这个:

If (text IsNot Nothing) AndAlso (text.Trim().Length <> 0) Then
    Me.dataReceived.Text = text
End If

我对 SerialPort 类不太熟悉,但我会尽力解释发生了什么。当有新数据通过串口进来时,串口会引发数据接收事件。然后,您的代码会读取所有已收到的现有数据。当您调用 ReadExisting 方法时,它只返回到目前为止已收到的内容。它不会在返回之前等待所有数据进入。然后它调用 ReceivedText 方法,该方法将某些控件的值设置为接收到的文本。InvokeRequired 和 Invoke 调用只是为了让您回到 UI 线程。显然 SerialPort 的 DataReceived 事件可能会在单独的线程上引发,因此您需要返回 UI 线程,然后才能对表单上的任何控件执行任何操作。我建议的更改只是检查以确保在更改文本框的值之前收到的文本不为空或为空。该代码的奇怪之处在于它继续从串行端口读取,直到它不再打开。我不认为你会想要那样做。相反,我认为在每个 DataReceived 事件中,您只需调用 ReadExisting 一次,然后期望在下次收到更多数据时再次引发它。通过在循环中连续调用 ReadExisting,如果没有更多数据要读取,它必须返回空字符串或空字符串,这就是文本框被空白的原因。该代码的奇怪之处在于它继续从串行端口读取,直到它不再打开。我不认为你会想要那样做。相反,我认为在每个 DataReceived 事件中,您只需调用 ReadExisting 一次,然后期望在下次收到更多数据时再次引发它。通过在循环中连续调用 ReadExisting,如果没有更多数据要读取,它必须返回空字符串或空字符串,这就是文本框被空白的原因。该代码的奇怪之处在于它继续从串行端口读取,直到它不再打开。我不认为你会想要那样做。相反,我认为在每个 DataReceived 事件中,您只需调用 ReadExisting 一次,然后期望在下次收到更多数据时再次引发它。通过在循环中连续调用 ReadExisting,如果没有更多数据要读取,它必须返回空字符串或空字符串,这就是文本框被空白的原因。

于 2012-05-17T12:18:32.540 回答
0

&=正在连接你的文字。用于=覆盖标签。

Me.dataReceived.Text = text
于 2012-05-17T11:18:49.077 回答
0

我不确定发生了什么,但它可能text在设置dataReceived.Text. 试试这个,

Private Sub ReceivedText(ByVal datatext As String)
     Me.Invoke(Sub()   
                    'To output to the text box:
                    Me.dataReceived.Text = datatext

                    Me.temp.Text = datatext
                    hmd.Text = datatext
               End Sub)
    End If
End Sub

我改为text因为datatext可能text与表单本地text属性混淆。我还将标签/文本框的文本属性设置移动到使用 lambda 的调用中(请注意,此语法是新语法,仅适用于 VB 2010)。我觉得您的调用语句可能没有正确传递字符串值。我还删除了对 的检查InvokeRequired,因为调用在这两种情况下都有效,而且看起来你可能只是每次都在进行线程调用。

如果它为您编译,它应该可以工作。如果没有,它可能RecievedText永远不会被调用。设置一些断点并单步执行代码以查看它datatext有一个值并且ReceivedText实际被调用。

于 2012-05-17T13:51:33.317 回答