Добавление текста в richTextBox в другом потоке и файле кода - PullRequest
1 голос
/ 28 сентября 2011

С целью создания программы для взаимодействия с устройством с последовательным портом я недавно начал изучать vb.net. Чтобы сохранить структуру в чистоте, код vb был разделен на две части; Первый - это код для инициализации, нажатия кнопок и т. д., а второй - для управления коммуникационным портом. Соответственно, они называются «MainWindow.xaml.vb» и «ComPortManager.vb».

В 'comPortManager.vb':

Dim RXArray(2047) As Char ' Array to hold received characters
Dim RXCnt As Integer      ' Received character count

    Private Sub comPort_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles comPort.DataReceived
        Do
            RXCnt = 0
            Do
                 'Populates the array, RXArray and counts the number of characters, RXCnt
            Loop Until (comPort.BytesToRead = 0) 'Keeps reading the buffer until it is empty
            'Code for posting to the richTextBox
        Loop Until (comPort.BytesToRead = 0) 'If the buffer has been written to in the meantime, repeat
    End Sub

MainWindow.xaml содержит ленту (выпуск Microsoft за октябрь 2010 г.) с элементами управления настройками, открытием, закрытием и отправкой (пока это все отдельно и просто), а остальная часть окна - richTextBox, озаглавленная « RichTextBox1.

Поиск способа публикации содержимого RXArray в RichTextBox1 породил множество предложений, основанных на Invoke или BeginInvoke. Действительно, рабочие примеры были успешно выполнены, но весь код, связанный с Invoke, был в одном файле, код позади. (Поправьте меня, если я ошибаюсь, но это звучит нормально для небольших программ, но может раздуться от средних до больших программ, поэтому я хочу найти лучшее решение)

Код, наиболее близкий к выполнению (я полагаю), выглядит следующим образом:

'В comPort_DataReceived ... после заполнения массива

If RichTextBox1.InvokeRequired Then
                RichTextBox1.Invoke(New MethodInvoker(AddressOf Display))
            End If

'и обратно в основной код

Public Delegate Sub MethodInvoker()

Private Sub Display()
    RichTextBox1.AppendText(New String(RXArray, 0, RXCnt))
End Sub

У этого есть несколько проблем, и я не уверен, в каком направлении идти на этом этапе. RichTextBox1 находится в другом потоке, поэтому не распознается; InvokeRequired не является членом System.Windows.Controls.RichTextBox, аналогично с Invoke; и, наконец, в примерах делегат под названием MethodInvoker никогда не указывался выше.

Любая помощь по этой теме наиболее ценится. В эти несколько недель Invoke, BeginInvoke и т. Д. Несколько ускользнули от моего понимания. С уважением, Джонатан

1 Ответ

2 голосов
/ 28 сентября 2011

у нас есть крупномасштабное приложение, текстовое поле которого имеет статус нескольких потоков, добавляемых к нему одновременно и из разных форм. это глупая версия:

Public Sub addToMessageBox(ByVal msg As String)
    If Me.InvokeRequired Then
      Dim d As New AddToMessageBoxDelegate(AddressOf Me.addToMessageBox)
      Me.BeginInvoke(d, New Object() {msg})
    Else
      Try
        Me.MessageBox.AppendText("--" + msg + vbCrLf)
      Catch ex As Exception
      End Try
    End If
  End Sub

Делегат объявляется в начале

Private Delegate Sub AddToMessageBoxDelegate(ByVal msg As String)

Самая большая разница, которую я вижу, состоит в том, что я использую beginInvoke () и InvokeRequired () родительского класса. Я бы сказал, попробуй. Вызовите parentClass.AddToMessageBox («Текст, который вы хотите добавить»), где вы вызываете display ().

...