user3810361
user3810361

Reputation: 43

How to select specific colored text in a RichTextBox control?

I want to select specific colored text in a RichTextBox. For example, if I want to select the blue colored text shown in the image below, how can i do it?

Example of rich text content

Upvotes: 0

Views: 89

Answers (2)

Brian Rogers
Brian Rogers

Reputation: 129687

Here is the basic technique:

  • Starting from a particular index (perhaps the current cursor position), loop over the text of the RichTextBox and select each character one-by-one.
  • You can look at the SelectionColor property to determine whether the selected character has the color you are looking for.
  • Once you've found a character of the desired color, remember its index.
  • Continue looping until you've found a character that is not the color you are interested in (or you've reached the end of the text); remember that index.
  • You can now select the text between the two indexes: Select(firstIndex, secondIndex - firstIndex).

You can create an extension method for the RichTextBox which encapsulates the above into a nice easy-to-use method:

public static class RichTextExtensions
{
    /// <summary>
    /// Searches for text in a RichTextBox control by color and selects it if found.
    /// </summary>
    /// <param name="rtb">The target RichTextBox.</param>
    /// <param name="color">The color of text to search for.</param>
    /// <param name="startIndex">The starting index to begin searching from (optional).  
    /// If this parameter is null, the search will begin at the point immediately
    /// following the current selection or cursor position.</param>
    /// <returns>If text of the specified color was found, the method returns the index 
    /// of the character following the selection; otherwise, -1 is returned.</returns>
    public static int SelectTextByColor(this RichTextBox rtb, Color color, int? startIndex = null)
    {
        if (rtb == null || rtb.Text.Length == 0) return -1;
        if (startIndex == null)
        {
            if (rtb.SelectionLength > 0) 
                startIndex = rtb.SelectionStart + rtb.SelectionLength;
            else if (rtb.SelectionStart == rtb.Text.Length) 
                startIndex = 0;
            else 
                startIndex = rtb.SelectionStart;
        }
        int matchStartIndex = rtb.FindTextByColor(color, startIndex.Value, true);
        if (matchStartIndex == rtb.Text.Length)
        {
            rtb.Select(matchStartIndex, 0);
            return -1;
        }
        int matchEndIndex = rtb.FindTextByColor(color, matchStartIndex, false);
        rtb.Select(matchStartIndex, matchEndIndex - matchStartIndex);
        return matchEndIndex;
    }

    private static int FindTextByColor(this RichTextBox rtb, Color color, int startIndex, bool match)
    {
        if (startIndex < 0) startIndex = 0;
        for (int i = startIndex; i < rtb.Text.Length; i++)
        {
            rtb.Select(i, 1);
            if ((match && rtb.SelectionColor == color) || 
                (!match && rtb.SelectionColor != color))
                return i;
        }
        return rtb.Text.Length;
    }
}

You can call the extension method as shown below. Note that if your RichTextBox control has HideSelection turned on (it will by default), you'll need to set the focus back to the RichTextBox in order to see the selected text.

richTextBox1.SelectTextByColor(Color.Blue);
richTextBox1.Focus();

If you want the search to start from a particular index (e.g. the beginning of the text) rather than the current cursor position, you can pass that index to the method as the second parameter:

richTextBox1.SelectTextByColor(Color.Blue, 0);

Upvotes: 1

TaW
TaW

Reputation: 54433

This is a function that will return all character positions with a certain color:

List<int> getColorPositions(RichTextBox rtb, Color col)
{
    List<int> pos = new List<int>();
    for (int i = 0; i < rtb.Text.Length; i++)
    {
        rtb.SelectionStart = i;
        richTextBox1.SelectionLength = 1;
        if (rtb.SelectionColor.ToArgb() == col.ToArgb() ) pos.Add(i);
    }
    return pos;
}

It is up to you to pick and select the portions you are interested in..

If you are sure only one portion has the color you seek you can select that portion like this:

rtb.SelectionStart = pos[0]; 
rtb.SelectionLength = pos.Count;

But of course there may be several portions and you need to decide which to select/highlight. Note that only one portion of text can be selected/highlighted at a time!

Upvotes: 1

Related Questions