Добавление текста в richTextBox в другом потоке и файле кода

Намереваясь создать программу для взаимодействия с устройством с последовательным портом, я недавно начал изучать 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 и т. Д. Несколько ускользнули от моего понимания. С уважением, Джонатан


person Jonathan    schedule 28.09.2011    source источник


Ответы (1)


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

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 ().

person Chris Santiago    schedule 28.09.2011
comment
Спасибо за ответ, я попробую. - person Jonathan; 29.09.2011