.netvb.nettext-coloring

VB.net richtextbox multiple colors to specified words


So my program reads a text file into a richtextbox. For example, I want all the words "echo" "pause" "setlocal" to be blue, "%" to be orange ", "rem" "::" to be green and so on. A lot of different words get different colors. Yes, the idea is so the richtextbox reads .bat files like notepad++ do color-wise.

I've figured out how to set a color to one word

Private Sub PreviewRTB_TextChanged(sender As Object, e As EventArgs) Handles PreviewRTB.TextChanged
    PreviewRTB.Multiline = True
    PreviewRTB.ScrollBars = ScrollBars.Vertical

    'Set Colors
    Dim index As Integer = 0
    Dim c_blue As String = "Echo"

    While index <> -1
        index = PreviewRTB.Find(c_blue, index, RichTextBoxFinds.WholeWord)
        If index <> -1 Then
            PreviewRTB.SelectionStart = index
            PreviewRTB.SelectionLength = c_blue.Length
            PreviewRTB.SelectionColor = Color.Blue
            index += c_blue.Length
        End If
    End While

But where do I set the rest of the words under dim c_blue? I tried Dim c_blue As String = "Echo" & "setlocal" & "pause" also tried to use + between as well, but it doesn't work. And how do I progress to add another color to other words? Thanks!


Solution

  • For simple coloring, provided that the text isn't too long, something like this will do:

    Dim KeyWords As List(Of String) = New List(Of String)(New String() {"this", "word", "color"})
    Dim KeyWordsColors As List(Of Color) = New List(Of Color)(New Color() {Color.Blue, Color.Red, Color.Green})
    Private Sub PreviewRTB_TextChanged(sender As Object, e As EventArgs) Handles PreviewRTB.TextChanged
        Dim words As IEnumerable(Of String) = PreviewRTB.Text.Split(New Char() {" "c, ".", ",", "?", "!"})
        Dim index As Integer = 0
        Dim rtb As RichTextBox = sender 'to give normal color according to the base fore color
        For Each word As String In words
            'If the list contains the word, then color it specially. Else, color it normally
            'Edit: Trim() is added such that it may guarantee the empty space after word does not cause error
            coloringRTB(sender, index, word.Length, If(KeyWords.Contains(word.ToLower().Trim()), KeyWordsColors(KeyWords.IndexOf(word.ToLower().Trim())), rtb.ForeColor))
            index = index + word.Length + 1 '1 is for the whitespace, though Trimmed, original word.Length is still used to advance
        Next
    End Sub
    
    Private Sub coloringRTB(rtb As RichTextBox, index As Integer, length As Integer, color As Color)
        Dim selectionStartSave As Integer = rtb.SelectionStart 'to return this back to its original position
        rtb.SelectionStart = index
        rtb.SelectionLength = length
        rtb.SelectionColor = color
        rtb.SelectionLength = 0
        rtb.SelectionStart = selectionStartSave
        rtb.SelectionColor = rtb.ForeColor 'return back to the original color
    End Sub
    

    The idea here is pretty straight forward:

    1. List the words you want to color
    2. List the colors of those words
    3. When the RTB text is changed, parse it with String.Split word by word (note that the condition "RTB text is changed" can be changed with anything you want)
    4. Check the parsed word. If it is found, start coloring that word. If not, color it with default color
    5. Go to the next word, till the text reading is finished.
    6. Don't forget to increase the current index of the checker according to the word.Length +1 for the whitespace

    The result will be something like this:

    enter image description here

    Next (2)

    enter image description here

    Next (3)

    enter image description here

    Next (4)

    enter image description here

    Next (5)

    enter image description here

    Note: If the text gets too long, consider of creating a timer (or some other module) to periodically check your RTB instead of checking the text when the text changed. Thus, when the text changed. You reset the timer. When the text is not changed after sometimes, then you start to implement the coloring logic for all the text. This way, you make the word-color checker work significantly less.