RichTextBox选择行为奇怪

时间:2014-07-21 12:01:25

标签: vb.net richtextbox

WinForms,Windows 8.1

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

对于突出显示,我会跟踪前一个文本,将其与当前文本进行比较,并突出显示当前文本中不在前一个文本中的任何内容。例如,如果文件最初包含“一二四”并且我将其更改为“一二三四”,则在RichTextBox中将突出显示单词“three”。

正在发生的事情是文本没有突出显示,除非我在包含突出显示的循环之前包含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

1 个答案:

答案 0 :(得分:0)

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

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