1

I've recently found this interesting code that changes the color of the 'key words' in a RichTextBox control, from this link Color specific words in RichtextBox

The problem is that when some letters of the word are deleted, the word is still colored.

eg. keyword is AND and it is red, but if i delete letter N, the remaining letters AD are still red.

I want to able to set it back to the RichTextBox ForeColor.

I know that I should probably set the ForeColor back to white (my default color) before the keywords check, but nothing I tried is working.

Any ideas?

Code by Sajeetharan

private void Rchtxt_TextChanged(object sender, EventArgs e)
    {
        this.CheckKeyword("and", Color.Red, 0);
        this.CheckKeyword("or", Color.Red, 0);
    }

private void CheckKeyword(string word, Color color, int startIndex)
{
    if (this.Rchtxt.Text.Contains(word))
    {
        int index = -1;
        int selectStart = this.Rchtxt.SelectionStart;

        while ((index = this.Rchtxt.Text.IndexOf(word, (index + 1))) != -1)
        {
            this.Rchtxt.Select((index + startIndex), word.Length);
            this.Rchtxt.SelectionColor = color;
            this.Rchtxt.Select(selectStart, 0);
            this.Rchtxt.SelectionColor = Color.Black;
        }
    }
}
Jimi
  • 29,621
  • 8
  • 43
  • 61
Ljutgu Las
  • 75
  • 8

2 Answers2

2

You can reset the color of complete text to the default color (black in this case) and then run your usual keyword coloring to apply the colors again.

    private void Rchtxt_TextChanged(object sender, EventArgs e)
    {
        this.CheckKeyword(Rchtxt.Text, Color.Black, 0);
        this.CheckKeyword("and", Color.Red, 0);
        this.CheckKeyword("or", Color.Red, 0);
    }
Harsh
  • 3,683
  • 2
  • 25
  • 41
1

Use this answer as a reference for the results:
How to color different words with different colors in a RichTextBox

This class object is used keep track of the words to color and the related color to use when one of these words is written or changed:
(The linked answer explains how to fill the list with words and related colors)

public class ColoredWord
{
    public string Word { get; set; }
    public Color WordColor { get; set; }
}

public List<ColoredWord> ColoredWords = new List<ColoredWord>();

In the RichTextBox KeyUp() event, check whether a word in the list is being inserted or modified:
Here I'm using the KeyUp() event because at the moment it's raised, the word has already been inserted/modified.

private void richTextBox1_KeyUp(object sender, KeyEventArgs e)
{
    if ((e.KeyCode >= Keys.Left & e.KeyCode <= Keys.Down)) return;
    if (e.KeyCode == Keys.ShiftKey || e.KeyCode == Keys.Alt || e.KeyCode == Keys.ControlKey) return;

    int CurrentPosition = richTextBox1.SelectionStart;
    int[] WordStartEnd;

    string word = GetWordFromPosition(richTextBox1, CurrentPosition - 1, out WordStartEnd);
    ColoredWord result = ColoredWords.FirstOrDefault(s => s.Word == word.ToUpper());
    SetSelectionColor(richTextBox1, result, CurrentPosition, WordStartEnd);

    if (e.KeyCode == Keys.Space && result == null) 
    {
        word = GetWordFromPosition(richTextBox1, CurrentPosition + 1, out WordStartEnd);
        result = ColoredWords.FirstOrDefault(s => s.Word == word.ToUpper());
        SetSelectionColor(richTextBox1, result, CurrentPosition, WordStartEnd);
    }
}

These are the helpers methods that are used to color a Word when it's included in the list and to extract the word from the current caret position.

The case when an already colored word is split by a space char, thus both ends lose their color, is handled in the KeyUp() event (the code part is: if (e.KeyCode == Keys.Space && result == null).

private void SetSelectionColor(RichTextBox ctl, ColoredWord word, int Position, int[] WordStartEnd)
{
    ctl.Select(WordStartEnd[0], WordStartEnd[1]);
    if (word != null)
    {
        if (ctl.SelectionColor != word.WordColor)
            ctl.SelectionColor = word.WordColor;
    }
    else
    {
        if (ctl.SelectionColor != ctl.ForeColor)
            ctl.SelectionColor = ctl.ForeColor;
    }
    ctl.SelectionStart = Position;
    ctl.SelectionLength = 0;
    ctl.SelectionColor = richTextBox1.ForeColor;
}

private string GetWordFromPosition(RichTextBox ctl, int Position, out int[] WordStartEnd)
{
    int[] StartEnd = new int[2];
    StartEnd[0] = ctl.Text.LastIndexOf((char)Keys.Space, Position - 1) + 1;
    StartEnd[1] = ctl.Text.IndexOf((char)Keys.Space, Position);
    if (StartEnd[1] == -1) StartEnd[1] = ctl.Text.Length;
    StartEnd[1] -= StartEnd[0];
    WordStartEnd = StartEnd;
    return ctl.Text.Substring(StartEnd[0], StartEnd[1]);
}
Jimi
  • 29,621
  • 8
  • 43
  • 61