2

I want to select the text that is between the last '{' and '}' of a richtextbox text. I have the next code, but I have an error on the "LastIndexOf" function and I don't know how to fix it. Can someone give me some help?

    private void highlightText()
    {
        mRtbxOperations.SelectionStart = mRtbxOperations.Text.LastIndexOf(@"{", 1, mRtbxOperations.SelectionStart);
        mRtbxOperations.SelectionLength = mRtbxOperations.Text.IndexOf(@"}", mRtbxOperations.SelectionStart, mRtbxOperations.Text.Length - 1);
        mRtbxOperations.SelectionBackColor = Color.LightBlue;
        mRtbxOperations.SelectionFont = new Font(mRtbxOperations.SelectionFont, FontStyle.Underline);
        mRtbxOperations.SelectionLength = 0;
    }

LastIndexOf Error:

The count must be positive and must refer to a location within the string, array or collection. Parameter name: count

Imrik
  • 674
  • 2
  • 14
  • 32
  • possible duplicate of [Selectively coloring text in RichTextBox](http://stackoverflow.com/questions/455713/selectively-coloring-text-in-richtextbox) – Hans Passant Mar 19 '14 at 12:03

2 Answers2

1

Seems that you're getting out of the text bounds. When you are getting a substring or an index, you always should use the string bounds, or a substring bounds. Also, you need to check that the selection is valid.

I would rewrite your code as follows:

    private void highlightText()
    {
        Selection selection = GetSelection(mRtbxOperations.Text);
        if (selection == null)
            return;
        mRtbxOperations.SelectionStart = selection.Start;
        mRtbxOperations.SelectionLength = selection.Length;
        mRtbxOperations.SelectionBackColor = Color.LightBlue;
        mRtbxOperations.SelectionFont = new Font(mRtbxOperations.SelectionFont,   
            FontStyle.Underline);
    }

    private static Selection GetSelection(string text)
    {
        int sIndex = text.LastIndexOf(@"{");
        if (sIndex == -1)
            return null;
        int eIndex = text.IndexOf(@"}", sIndex);
        if (eIndex == -1)
            return null;

        return new Selection(sIndex + 1, eIndex);
    }

    public class Selection
    {
        public int Start { get; set; }
        public int End { get; set; }

        public int Length
        {
            get
            {
                return End - Start;
            }
        }

        public Selection(int startIndex, int endIndex)
        {
            this.Start = startIndex;
            this.End = endIndex;
        }
    }
Daniel Peñalba
  • 30,507
  • 32
  • 137
  • 219
  • I have the same problem that in the other solution, but I wont to recieve the lastIndexOf my '{' near my mouse click on the text. I mean... I click on my richedTextBox and I want to select the part of text that have "{" and "}" nearest of my mouseclick, so I need to do "mRtbOperations.Text.LastIndexOf(@"{", 0, /*mouseClickPosition*/);" and it brokes again with the same error. Thanks! – Imrik Mar 19 '14 at 14:51
  • Ok. I understand. See my edits, using LastIndexOf. It should work. – Daniel Peñalba Mar 19 '14 at 15:07
1

You LastIndexOf parameters are messed up, as well as the Length of the selection, where you need to substract the starting point in order to get the proper length.

Try a simpler version:

int textStart = mRtbxOperations.Text.LastIndexOf(@"{",
                                                 mRtbxOperations.SelectionStart);
if (textStart > -1) {
  int textEnd = mRtbxOperations.Text.IndexOf(@"}", textStart);
  if (textEnd > -1) {
    mRtbxOperations.Select(textStart, textEnd - textStart + 1);
    mRtbxOperations.SelectionBackColor = Color.LightBlue;
  }
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • this works, but I want to recieve the lastIndexOf my '{' near my mouse click on the text. I mean... I click on my richedTextBox and I want to select the part of text that have "{" and "}" nearest of my mouseclick, so I need to do "mRtbOperations.Text.LastIndexOf(@"{", 0, /*mouseClickPosition*/);" and it brokes again with the same error. – Imrik Mar 19 '14 at 14:46
  • @Imrik Then I don't think you want LastIndexOf. Try `int textStart = mRtbxOperations.Text.IndexOf(@"{", mRtbxOperations.SelectionStart);` – LarsTech Mar 19 '14 at 14:50
  • I need LastIndexOf because my text is, for example: "if (valueGenMaxProp != 0) { myPaint(); } if (firstLap == true) { pbxTriangle.Location = new Point(200, 100); }" And I need to underline the first or second segment, it depends on the mouseClick position, the "mRtbxOperations.SelectionStart". Thanks! – Imrik Mar 19 '14 at 14:52
  • @Imrik OK, then use LastIndexOf in place of IndexOf in the code I have in my previous comment. It will find the "{" character that comes *before* the current SelectionStart position. Other than that, it's a little unclear what you are attempting to do. Maybe provide the text in the RTB control. Also, when are you calling this highlight code? – LarsTech Mar 19 '14 at 14:56
  • I have one more problem now. I want to higlight with yellow color, so I set the color property like that: "mRtbxOperations.SelectionBackColor = Color.Yellow;", but before seeing the yellow color I always see a blue color like the color that appears when you use your mouse to underline some text. What can I do? Thanks! – Imrik Mar 19 '14 at 15:22
  • @Imrik Sounds like the default highlight color. Try setting the SelectionLength to zero in your first line. – LarsTech Mar 19 '14 at 15:27
  • Perfect, but I finally set the SelectionLength in the same position as the mouse click, thank you! – Imrik Mar 20 '14 at 07:11