【问题标题】:RichTextBox selection behaving oddlyRichTextBox 选择行为异常
【发布时间】:2014-09-11 22:18:29
【问题描述】:

WinForms,Windows 8.1

我正在尝试使用 RichTextBox 突出显示对文本文件的更改。应该是小菜一碟。我正在使用 FileSystemWatcher 监视文本文件,并在文件更改时将其加载到 RichTextBox。

对于突出显示,我会跟踪以前的文本,将其与当前文本进行比较,然后突出显示当前文本中未出现在先前文本中的任何内容。例如,如果文件最初包含“一二四”,而我将其更改为“一二三四”,则 RichTextBox 中的“三”一词将突出显示。

发生的情况是文本没有突出显示,除非我在突出显示的循环之前包含 MsgBox("") 或 Application.DoEvents()。使用延迟循环、Thread.Sleep() 或 RichTextBox.Invalidate 不会使其工作。

注意:如果您尝试自己复制此内容,则该行为仅在我从文件中获取文本时才会出现。如果我在表单上放置一个 TextBox 和 Button,并在 Button.Click 上使用 TextBox.Text 更新 RichTextBox.Text,则代码可以正常工作。

Public Class Form1
    Public sCurrentDir As String = My.Computer.FileSystem.CurrentDirectory
    Public sCurrent As String = ""
    Public sPrevious As String = ""


    '******************************************************
    Private Function FileIsOpen(sFile)
        Try
            Dim FS As IO.FileStream = IO.File.Open(sFile, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.None)  'Create file stream with read-only exclusive access

            FS.Close()
            FS.Dispose()
            FS = Nothing

            Return False
        Catch ex As IO.IOException
            Return True
        Catch ex As Exception
            MessageBox.Show("Error: " & ex.Message)

            Return True
        End Try
    End Function


    '******************************************************
    Private Sub FileSystemWatcher1_Changed(sender As Object, e As IO.FileSystemEventArgs) Handles FileSystemWatcher1.Changed
        Do Until Not FileIsOpen(sCurrentDir & "\test.txt")
        Loop

        RichTextBox1.Text = IO.File.ReadAllText(sCurrentDir & "\test.txt")
    End Sub


    '******************************************************
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        RichTextBox1.Text = IO.File.ReadAllText(sCurrentDir & "\test.txt")
    End Sub


    '******************************************************
    Private Sub RichTextBox1_TextChanged(sender As Object, e As EventArgs) Handles RichTextBox1.TextChanged
        Dim aCurrent(), aPrevious()
        Dim i As Integer

        If (RichTextBox1.Text <> sCurrent) Then  'Text is different (rather than simply being replaced with the same text)
            'Erase previous selection(s)
            RichTextBox1.SelectedText = ""
            RichTextBox1.SelectAll()
            RichTextBox1.SelectionBackColor = RichTextBox1.BackColor

            sPrevious = sCurrent
            sCurrent = RichTextBox1.Text

            aCurrent = Split(sCurrent)
            aPrevious = Split(sPrevious)

            'This DOES make the highlighting code work
            'MsgBox("")

            'This DOES make the highlighting code work
            'Application.DoEvents()

            'This does NOT make the highlighting code work
            'System.Threading.Thread.Sleep(1000)

            'This does NOT make the highlighting code work
            'For i = 0 To 500000
            'Next

            For i = 0 To aCurrent.Count - 1
                If (sPrevious.IndexOf(aCurrent(i)) = -1) Then
                    RichTextBox1.Select(RichTextBox1.Text.IndexOf(aCurrent(i)), Len(aCurrent(i)))

                    RichTextBox1.SelectionBackColor = Color.Yellow
                End If
            Next

            'This does NOT make the highlighting code work
            'RichTextBox1.Invalidate()

            RichTextBox1.SelectionLength = 0  'Otherwise the last selected word will still be selected
        End If
    End Sub
End Class

【问题讨论】:

  • 但是 A)如果我通过 Button.Click 事件使用本地文本更新 RichTextBox,则不会发生此问题;只有当我从文件中读取它时才会发生;和 B) 将 MsgBox 或 DoEvents before 放在循环不应该对冻结 GUI 的循环产生任何影响。 (为什么操作系统不会在循环完成后处理备份的消息?)放置 MsgBox 或 DoEvents——我认为这会迫使操作系统处理任何备份的消息——之后循环也不会导致代码正确突出显示。

标签: vb.net richtextbox


【解决方案1】:

通过尝试打开测试文件,您会触发 FileChanged 事件,这会导致代码尝试打开测试文件,从而导致 FileChanged 事件触发等等。

循环似乎没有必要,或者您需要使用 FileSystemWatcher 的 EnableRaisingEvents 属性关闭事件。

【讨论】:

  • 你一定是指 FileSystemWatcher1_Changed 中的空循环,而不是 RichTextBox1_TextChanged 中的那个?假设是前者,那是为了防止几乎总是“文件正在被另一个程序使用”错误。我在 FileSystemWatcher1_Changed 的​​开头禁用了 EnableRaisingEvents,并在最后重新启用它,现在它似乎按预期工作。那么 RichTextBox_TextChanged 的​​幕后发生了什么可能导致 MsgBox 或 DoEvents 使其工作?
  • @Brian TextChanged 事件中没有任何内容。 FileChanged 事件和 FileIsOpen 方法中的所有内容。 FileChanged方法调用FileIsOpen,打开文件,导致FileChanged方法再次发生,再次调用FileIsOpen,yada,yada,yada。
猜你喜欢
  • 1970-01-01
  • 2013-04-26
  • 1970-01-01
  • 2020-04-23
  • 2021-02-16
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
  • 1970-01-01
相关资源
最近更新 更多