Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Way to obtain the word cursor is on, in WPF RichTextBox Control

I would like to know how I can get the word that current cursor is on, in WPF RichTextBox. I am aware that RichTextBox has Selection Property. However, this only gives me the text that is highlighted in the RichTextBox. Instead I would like to know the word the cursor is on even if the whole word is not highlighted.

Any tips are appreciated.

like image 769
Shintaro Takechi Avatar asked Jul 31 '12 01:07

Shintaro Takechi


3 Answers

Attach this function to an arbitrary RichTextBox, now called testRTB, and see Output window for results:

private void testRTB_MouseUp(object sender, MouseButtonEventArgs e)
{
        TextPointer start = testRTB.CaretPosition;  // this is the variable we will advance to the left until a non-letter character is found
        TextPointer end = testRTB.CaretPosition;    // this is the variable we will advance to the right until a non-letter character is found

        String stringBeforeCaret = start.GetTextInRun(LogicalDirection.Backward);   // extract the text in the current run from the caret to the left
        String stringAfterCaret = start.GetTextInRun(LogicalDirection.Forward);     // extract the text in the current run from the caret to the left

        Int32 countToMoveLeft = 0;  // we record how many positions we move to the left until a non-letter character is found
        Int32 countToMoveRight = 0; // we record how many positions we move to the right until a non-letter character is found

        for (Int32 i = stringBeforeCaret.Length - 1; i >= 0; --i)
        {
            // if the character at the location CaretPosition-LeftOffset is a letter, we move more to the left
            if (Char.IsLetter(stringBeforeCaret[i]))
                ++countToMoveLeft;
            else break; // otherwise we have found the beginning of the word
        }


        for (Int32 i = 0; i < stringAfterCaret.Length; ++i)
        {
            // if the character at the location CaretPosition+RightOffset is a letter, we move more to the right
            if (Char.IsLetter(stringAfterCaret[i]))
                ++countToMoveRight;
            else break; // otherwise we have found the end of the word
        }



        start = start.GetPositionAtOffset(-countToMoveLeft);    // modify the start pointer by the offset we have calculated
        end = end.GetPositionAtOffset(countToMoveRight);        // modify the end pointer by the offset we have calculated


        // extract the text between those two pointers
        TextRange r = new TextRange(start, end);
        String text = r.Text;


        // check the result
        System.Diagnostics.Debug.WriteLine("[" + text + "]");
}

Change Char.IsLetter(...) to Char.IsLetterOrDigit(...) or whatever else appropriately depending on whether you wish to keep digits as well.

Tip: extract this into an extension method in a separate assembly to access it whenever needed.

like image 198
Balázs Avatar answered Oct 20 '22 13:10

Balázs


OK so in order to solve this I brute forced it.

I used curCaret.GetTextInRun(LogicalDirection.Backward) and curCaret.GetTextInRun(LogicalDirection.Forward)

along with preCaretString.LastIndexOf(" ") and postCaretString.IndexOf(" ") plus other dividers that separates word and got the substrings.

Eventually I added the first half of string and second half of string to obtain the currently cursored word.

I bet there are cleverer way of doing this but at least this solved the problem

like image 38
Shintaro Takechi Avatar answered Oct 20 '22 13:10

Shintaro Takechi


You can get the current position of the cursor via CaretPosition.

Unfortunately there is no easy way to get the characters to the left/right of the caret position. The only way I know of to get text out of a RichTextBox is in this answer, which is a bit convoluted. But it will accomplish what is necessary.

like image 1
ikh Avatar answered Oct 20 '22 13:10

ikh