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 スレッドに戻る必要があります。私が提案した変更は、テキスト ボックスの値を変更する前に、受け取ったテキストが null または空でないことを確認するためだけにチェックしました。このコードの奇妙な点は、シリアル ポートが開かなくなるまで読み取りを続けることです。あなたがそうしたいとは思わないでしょう。むしろ、各 DataReceived イベントで、ReadExisting を 1 回呼び出すだけで、次にさらにデータを受信したときに再び発生することを期待するだけだと思います。ループ内で ReadExisting を継続的に呼び出すことにより、読み取るデータがなくなった場合は、null 文字列または空の文字列を返す必要があります。これが、テキスト ボックスが空白になっている理由です。このコードの奇妙な点は、シリアル ポートが開かなくなるまで読み取りを続けることです。あなたがそうしたいとは思わないでしょう。むしろ、各 DataReceived イベントで、ReadExisting を 1 回呼び出すだけで、次にさらにデータを受信したときに再び発生することを期待するだけだと思います。ループ内で ReadExisting を継続的に呼び出すことにより、読み取るデータがなくなった場合は、null 文字列または空の文字列を返す必要があります。これが、テキスト ボックスが空白になっている理由です。このコードの奇妙な点は、シリアル ポートが開かなくなるまで読み取りを続けることです。あなたがそうしたいとは思わないでしょう。むしろ、各 DataReceived イベントで、ReadExisting を 1 回呼び出すだけで、次にさらにデータを受信したときに再び発生することを期待するだけだと思います。ループ内で ReadExisting を継続的に呼び出すことにより、読み取るデータがなくなった場合は、null 文字列または空の文字列を返す必要があります。これが、テキスト ボックスが空白になっている理由です。

于 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しました。また、ラベル/テキスト ボックスのテキスト プロパティの設定を、ラムダを使用した呼び出しに移動しました (この構文は新しく、VB 2010 でのみ機能することに注意してください)。どういうわけか、invoke ステートメントが文字列値を適切に渡していなかったように感じます。また、呼び出しを行うことは両方の状況で機能し、とにかく毎回スレッド化された呼び出しを行っているように見えるため、のチェックを削除しました。datatexttexttextInvokeRequired

それがあなたのためにコンパイルされるなら、それはうまくいくはずです。そうでない場合は、RecievedText呼び出されていない可能性があります。いくつかのブレークポイントを設定し、コードをステップ実行しdatatextて、値があり、ReceivedText実際に呼び出されることを確認します。

于 2012-05-17T13:51:33.317 に答える