'How to change color of a specific word in a RichTextBox

I'm using the C# / WPF application. I want to change the color of all occurrences of a specific word in a text displayed inside a RichTextBox. I have tried several approaches but they all failed!



Solution 1:[1]

The method below is scanning content of the RichTextBox for specific text and color all found fragments to red color.

public static void TextSearchAndColor(RichTextBox rtb)
{   
    var find = "Text_To_Find";            
    TextRange searchRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);
    while(searchRange.FindTextInRange(find) is TextRange found)
    {
        found.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Red));
        searchRange = new TextRange(found.End, rtb.Document.ContentEnd);
    }            
}
public static class TextRangeExt
{
    public static TextRange FindTextInRange(this TextRange searchRange, string searchText)
    {
        TextRange result = null;
        int offset = searchRange.Text.IndexOf(searchText, StringComparison.OrdinalIgnoreCase);
        if (offset >= 0)
        {
            var start = GetTextPositionAtOffset(searchRange.Start, offset);
            result = new TextRange(start, GetTextPositionAtOffset(start, searchText.Length));
        }
        return result;
    }

    public static TextPointer GetTextPositionAtOffset(this TextPointer position, int offset)
    {
        for (TextPointer current = position; current != null; current = position.GetNextContextPosition(LogicalDirection.Forward))
        {
            position = current;
            var adjacent = position.GetAdjacentElement(LogicalDirection.Forward);
            var context = position.GetPointerContext(LogicalDirection.Forward);   

            switch (context)
            {
                case TextPointerContext.Text:
                    int count = position.GetTextRunLength(LogicalDirection.Forward);
                    if (offset <= count)
                    {
                        return position.GetPositionAtOffset(offset);
                    }
                    offset -= count;
                    break;
                case TextPointerContext.ElementStart:
                    if (adjacent is InlineUIContainer)
                        offset--;
                    break;
                case TextPointerContext.ElementEnd:
                    if (adjacent is Paragraph)
                        offset -= 2;
                    break;
            }
        }
        return position;
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1