在不同的线程和代码文件中将文本附加到 richTextBox

发布于 2024-12-07 01:46:43 字数 1789 浏览 1 评论 0原文

出于创建一个与串口设备交互的程序的目的,我最近开始学习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 年 10 月版本),其中包含用于设置、打开、关闭和发送的控件(暂时将其全部分开且简单),窗口的其余部分是一个名为“RichTextBox1”的 RichTextBox。

在寻找将 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 等有些让我无法理解。问候,乔纳森

With the intention of creating a program to interface with a serial port device, I recently started learning vb.net. To keep the structure neat the vb code has been split into two places; the first is the code behind for initialising, clicking buttons etc., whilst the second is for managing the comm port. Respectively, these are named 'MainWindow.xaml.vb' and 'ComPortManager.vb'.

In '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

The 'MainWindow.xaml' contains a ribbon (Microsoft's October 2010 release) with controls for settings, opening, closing and sending (keeping it all separate and simple for now), with the rest of the window being a richTextBox entitled 'RichTextBox1'.

The search for a way to post the contents of RXArray to RichTextBox1 brought up many suggestions based around Invoke or BeginInvoke. Indeed, working examples have been run successfully but all the code associated with Invoke has been in one file, the code behind. (Correct me if I'm wrong, but this sounds fine for small programs but could get bloated with medium to larger programs, hence me wanting to find a better solution)

The code closest to running (I believe) is as follows:

'In comPort_DataReceived... after populating the array

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

'and back in the main code

Public Delegate Sub MethodInvoker()

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

This has a few problems and I'm not sure in what direction to go at this stage. RichTextBox1 is in a different thread hence not recognised; InvokeRequired is not a member of System.Windows.Controls.RichTextBox, likewise with Invoke; and finally, in examples, the delegate entitled MethodInvoker was never stated as above.

Any help on this topic is most appreciated. In these few weeks, Invoke, BeginInvoke etc. have somewhat eluded my comprehension. Regards, Jonathan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

秋千易 2024-12-14 01:46:43

我们有一个大型应用程序,其中一个文本框具有同时附加到它的许多线程的状态,并且来自不同的形式。这是它的简化版本:

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()。我想说尝试一下。在调用display()的地方调用parentClass.AddToMessageBox("Text you Want to Append")。

we have a large scale application which a textbox has the status of many threads appended to it concurrently, and from different forms. this is a dumbed down version of it:

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

The delegate is declared at the begining

Private Delegate Sub AddToMessageBoxDelegate(ByVal msg As String)

the biggest difference that I can see is that I use the parent class's beginInvoke() and InvokeRequired(). I'd say give this a try. Call the parentClass.AddToMessageBox("Text you want to append") where you are calling the display().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文