Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 如何以编程方式从只读RichTextBox中删除文本?_Vb.net_Richtextbox - Fatal编程技术网

Vb.net 如何以编程方式从只读RichTextBox中删除文本?

Vb.net 如何以编程方式从只读RichTextBox中删除文本?,vb.net,richtextbox,Vb.net,Richtextbox,下面的代码旨在在只读RichTextBox中维护一个文本缓冲区,存储最大字符数,并始终保持滚动到底。它流式传输实时日志 但是在我试图保持最大字符数时,rtMessages.TextLength()在rtMessages.SelectedText=String.Empty之后不会改变,因此,如果没有防御性的If块,我将以一个无限循环结束,试图重复删除缓冲区的第一行 当我删除RichTextBox的只读属性时,此功能成功。似乎有点奇怪,因为AppendText成功了,但我知道选择是另一种野兽 我可以

下面的代码旨在在
只读
RichTextBox中维护一个文本缓冲区,存储最大字符数,并始终保持滚动到底。它流式传输实时日志

但是在我试图保持最大字符数时,
rtMessages.TextLength()
rtMessages.SelectedText=String.Empty
之后不会改变,因此,如果没有防御性的
If
块,我将以一个无限循环结束,试图重复删除缓冲区的第一行

当我删除
RichTextBox
只读属性时,此功能成功。似乎有点奇怪,因为
AppendText
成功了,但我知道选择是另一种野兽

我可以使
只读
RichTextBox
以编程方式修改吗?

Private Sub onNewData(ByRef data As String) Handles _server.clientSentData

    ' Add new text
    rtMessages.SelectionStart = rtMessages.TextLength()
    rtMessages.AppendText(data)

    ' Delete oldest text line-by-line until the whole buffer is shorter than MAX_TEXT_LENGTH characters
    Const MAX_TEXT_LENGTH = 200
    Dim textLength = rtMessages.TextLength()
    While textLength > MAX_TEXT_LENGTH
        Dim i As Int16 = 0
        Do While rtMessages.GetLineFromCharIndex(i) < 1
            i += 1
        Loop

        rtMessages.Select()
        rtMessages.SelectionStart = 0
        rtMessages.SelectionLength = i
        rtMessages.SelectedText = String.Empty
        rtMessages.SelectionLength = 0

        If rtMessages.TextLength() = textLength Then
            rtMessages.Clear()
            rtMessages.AppendText("[buffer trimming algorithm failed]")
            Exit While
        End If

        textLength = rtMessages.TextLength()
    End While

    ' Scroll down
    rtMessages.SelectionStart = rtMessages.TextLength()
    rtMessages.ScrollToCaret()
End Sub
Private子onNewData(ByRef数据作为字符串)处理\u server.clientSentData
'添加新文本
rtMessages.SelectionStart=rtMessages.TextLength()
rtMessages.AppendText(数据)
'逐行删除最早的文本,直到整个缓冲区小于最大文本长度字符
常量最大文本长度=200
Dim textLength=rtMessages.textLength()
而文本长度>最大文本长度
尺寸i为Int16=0
执行rtMessages.GetLineFromCharIndex(i)<1
i+=1
环
rtMessages.Select()
rtMessages.SelectionStart=0
rtMessages.SelectionLength=i
rtMessages.SelectedText=String.Empty
rtMessages.SelectionLength=0
如果rtMessages.TextLength()=TextLength,则
rtMessages.Clear()
rtMessages.AppendText(“[缓冲区修剪算法失败]”)
退出时
如果结束
textLength=rtMessages.textLength()
结束时
'向下滚动
rtMessages.SelectionStart=rtMessages.TextLength()
rtMessages.ScrollToCaret()文件
端接头
应该由

rtMessages.SelectionLength = i
编辑#1


将-1添加到SelectionLength,将丢失第一行的最后一个字符。在第二次运行时,只有1个字符会出现在第一行(您在第一次运行时错过的字符)。然后,您将尝试删除SelectionLength为0,并且每隔运行一次,您将获得相同的TextLength,这就是无限循环

您可以删除只读参数,编写appendtext代码,然后再次将richtextbox设置为只读。

我知道这是一个旧线程,但您可以绕过
只读问题,替换以下代码:

 rtMessages.Select()
 rtMessages.SelectionStart = 0
 rtMessages.SelectionLength = i
 rtMessages.SelectedText = String.Empty
 rtMessages.SelectionLength = 0
为此:

 rtMessages.Text = rtMessages.Text.Substring(i)
我不确定这是更好还是更差的性能,但它绕过了
RichTextBox
设置为
ReadOnly

编辑:

以下是用于测试此功能的完整代码(注意:我将代码添加到
按钮。单击
进行测试)

Private子按钮1\u单击(ByVal sender作为System.Object,ByVal e作为System.EventArgs)处理按钮1。单击
静态X为整数=0
X+=1
尺寸数据为String=“Line”&X.ToString&ControlChars.NewLine
Me.onNewData(数据)
端接头
专用子onNewData(ByRef数据作为字符串)
'添加新文本
rtMessages.SelectionStart=rtMessages.TextLength()
rtMessages.AppendText(数据)
'逐行删除最早的文本,直到整个缓冲区小于最大文本长度字符
常量最大文本长度为整数=200
Dim textLength As Integer=rtMessages.textLength()
而文本长度>最大文本长度
尺寸i为整数=0
执行rtMessages.GetLineFromCharIndex(i)<1
i+=1
环
'rtMessages.Select()
'rtMessages.SelectionStart=0
'rtMessages.SelectionLength=i
'rtMessages.SelectedText=String.Empty
'rtMessages.SelectionLength=0
rtMessages.Text=rtMessages.Text.Substring(i)
如果rtMessages.TextLength()=TextLength,则
rtMessages.Clear()
rtMessages.AppendText(“[缓冲区修剪算法失败]”)
退出时
如果结束
textLength=rtMessages.textLength()
结束时
'向下滚动
rtMessages.SelectionStart=rtMessages.TextLength()
rtMessages.ScrollToCaret()文件
端接头

尝试替换只读RichTextBox中的SelectedText时不起作用,使用SelectedRtf确实起作用:

  'rtMessages.Select()
  'rtMessages.SelectionStart = 0
  'rtMessages.SelectionLength = i
  'rtMessages.SelectedText = String.Empty
  'rtMessages.SelectionLength = 0

  rtMessages.Select(0, i)
  rtMessages.SelectedRtf = "{\rtf1\ansi}"

我可以确认这个
Sub
是在UI线程上调用的,而不是在某些通信线程上调用的。+1因为问题并不像看上去那么简单。。。我很惊讶以前没人提到这件事。你确定吗?我在我这边复制了你的错误,更改这一行对我来说很有帮助。当我更改代码时,错误会一直存在,直到我关闭
ReadOnly
。每一次迭代都给了我相同的文本长度,不是每一次迭代都给我相同的文本长度,除了第一次。对不起,我没有看到你编辑关于只读的内容。简单的解决方案是将RTB ReadOnly属性设置为false,运行代码,然后将ReadOnly设置回True。这里还有一篇关于同样问题的帖子:我想在某些情况下是可行的解决办法,但我的缓冲区很大;这也会中断当前滚动位置。@LightnessRacesinOrbit,滚动位置是否未被
rtMessages.SelectionStart=rtMessages.TextLength()和
rtMessages.ScrollToCaret()重置?在我的测试中,它滚动的很好。你在哪里使用多大的缓冲区?实际上我现在没有代码,所以这是从内存推测的,但是我的内存说用新文本替换整个文本缓冲区会丢失旧的滚动位置。不是吗?缓冲区将高达10KB左右。@LightnessRacesinOrbit,您认为它会将插入符号设置为顶部是正确的,但是,代码的最后两行将插入符号(和滚动位置)强制设置为底部啊,是的,忘记了我自己的问题。我说过我
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Static X As Integer = 0
    X += 1

    Dim Data As String = "Line " & X.ToString & ControlChars.NewLine
    Me.onNewData(Data)
End Sub

Private Sub onNewData(ByRef data As String)

    ' Add new text
    rtMessages.SelectionStart = rtMessages.TextLength()
    rtMessages.AppendText(data)

    ' Delete oldest text line-by-line until the whole buffer is shorter than MAX_TEXT_LENGTH characters
    Const MAX_TEXT_LENGTH As Integer = 200
    Dim textLength As Integer = rtMessages.TextLength()
    While textLength > MAX_TEXT_LENGTH
        Dim i As Integer = 0
        Do While rtMessages.GetLineFromCharIndex(i) < 1
            i += 1
        Loop

        'rtMessages.Select()
        'rtMessages.SelectionStart = 0
        'rtMessages.SelectionLength = i
        'rtMessages.SelectedText = String.Empty
        'rtMessages.SelectionLength = 0

        rtMessages.Text = rtMessages.Text.Substring(i)

        If rtMessages.TextLength() = textLength Then
            rtMessages.Clear()
            rtMessages.AppendText("[buffer trimming algorithm failed]")
            Exit While
        End If

        textLength = rtMessages.TextLength()
    End While

    ' Scroll down
    rtMessages.SelectionStart = rtMessages.TextLength()
    rtMessages.ScrollToCaret()

End Sub
  'rtMessages.Select()
  'rtMessages.SelectionStart = 0
  'rtMessages.SelectionLength = i
  'rtMessages.SelectedText = String.Empty
  'rtMessages.SelectionLength = 0

  rtMessages.Select(0, i)
  rtMessages.SelectedRtf = "{\rtf1\ansi}"