Search code examples
c#winformscontrolsrichtextbox

How do I color specific text in a RichTextBox?


So I was making a textbox and I thought that it would be cool if when the user types certain words, they'd get highlighted. I made a function using a RichTextBox, but it colors, half the text it is supposed to. Sometimes it doesn't even work.

Is a way to color every occurrence of a word?

My code:

private void ColorLines(RichTextBox text)
{
    string[] words = { "example","hi" };

    foreach (string s in text.Text.Split(' '))
    {
        int startIndex = text.Text.IndexOf(s);
        int length = s.Length;

        if (words.Contains(s))
        {
            text.Select(startIndex, length);
            text.SelectionColor = Color.Red;
        }
    }
}

I rewrote the script above several times, all being worse than the other. I've looked through other posts with the same problem, but it was or in VB or in WPF, or it was something different. I am searching for an efficient way using the WinForms.


Solution

  • This also colors instances of a word inside other words. So, I don't know if this works for what you need it for but apart from that it should do what you want.

    //I don't usually work with WinForms so idk if this is the correct way
    //to do this or if you can use "sender" or "e" instead of "richTextBox1"
    private void richTextBox_TextChanged(object sender, EventArgs e)
    {
        int tempint = richTextBox1.SelectionStart;
        richTextBox1.Select(0, richTextBox1.TextLength);
        richTextBox1.SelectionColor = Color.Black;
        richTextBox1.Select(tempint, 0);
        ColorLines(richTextBox1);
    }
    
    private void ColorLines(RichTextBox text)
    {
        string[] words = { "example", "hi"};
    
        foreach (string word in words)
        {
            if (text.Text.Contains(word))
            {
                int index = -1;
                int curselected = text.SelectionStart;
    
                while ((index = text.Text.IndexOf(word, (index + 1))) != -1)
                {
                    text.Select(index, word.Length);
                    text.SelectionColor = Color.Red;
                    text.Select(curselected, 0);
                    text.SelectionColor = Color.Black;
                }
            }
        }
    }
    

    Inspired by this legends answer

    enter image description here

    here's another version that doesn't color instances of a word inside other words but doesnt work when there's a symbol before or after the word like "," or "." without a space.

        private void richTextBox_TextChanged(object sender, EventArgs e)
        {
            int tempint = richTextBox1.SelectionStart;
            richTextBox1.Select(0, richTextBox1.TextLength);
            richTextBox1.SelectionColor = Color.Black;
            richTextBox1.Select(tempint, 0);
            ColorLines(richTextBox1);
        }
    
        private void ColorLines(RichTextBox text)
        {
            string[] words = { "example", "hi" };
            int startindex = 0;
    
            foreach (string word2 in text.Text.Split(' ').ToArray())
            {
                foreach (string word in words)
                {
                    if (word == word2)
                    {
                        int curselected = text.SelectionStart;
                        int length = word2.Length;
    
                        text.Select(startindex, length);
                        text.SelectionColor = Color.Red;
                        text.Select(curselected, 0);
                        text.SelectionColor = Color.Black;
                    }
                }
                startindex += word2.Length + 1;
            }
        }
    

    enter image description here