jeff
jeff

Reputation: 684

Get last entered word of RichTextBox using c#

How do I get the last entered word and its index position( word between two spaces. as soon as I press space I need to get the word) within a RichTextBox. I have used the following code to get the last entered word and its index position if the word is in the end of the RichTextBox document.

private void richTextBox_KeyPress(object sender, KeyPressEventArgs e){
         if(e.KeyChar == ' '){
         int i = richTextBox.Text.TrimEnd().LastIndexOf(' ');
        if(i != -1)  MessageBox.Show(richTextBox.Text.Substring(i+1).TrimEnd());
                }
      }

But how do I get the last entered word and its index position if I type in the middle of a sentence in the RTB( e.g. 'quick fox' is the sentence; If I write 'jumps' after 'fox' then using the above code I can get the last entered word. But if I position the cursor after 'quick' and write 'brown' after 'quick' how do I get the last entered word (i.e. brown) as soon as I press space.

Please help

Upvotes: 2

Views: 3250

Answers (4)

trashrobber
trashrobber

Reputation: 777

If you are looking for the last entered word, not just the last word in the box, you are going to need to create a collection of words in the box, then compare what has changed when new words are added.

just off the top of my head

    private string oldwords = "";
    private string newwords = "";
    private string lastword;
    private int index;

    private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
      if (e.KeyChar != ' ') return;
      findLastword();
    }

    private void findLastword()
    {
      newwords = richTextBox1.Text;
      lastword = newwords.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                          .Except(oldwords.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
                          .ToList().FirstOrDefault() ?? "";

      oldwords = newwords;
      index = newwords.IndexOf(lastword.FirstOrDefault());
    }

Upvotes: 0

King King
King King

Reputation: 63317

You can benefit from some Key events and flags:

bool newStart; 
int startIndex;
//SelectionChanged event handler for richTextBox1
private void richTextBox1_SelectionChanged(object sender, EventArgs e)
{
     //record the new SelectionStart
     if (newStart) startIndex = richTextBox1.SelectionStart;                        
}
//KeyDown event handler for richTextBox1
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
     newStart = char.IsControl((char)e.KeyCode) ||
                         ((int)e.KeyCode < 41 && (int)e.KeyCode > 36);
}
//KeyUp event handler for richTextBox1
private void richTextBox1_KeyUp(object sender, KeyEventArgs e)
{
     newStart = true;//This makes sure if we change the Selection by mouse
     //the new SelectionStart will be recorded.
}
//KeyPress event handler for richTextBox1
private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
   if (e.KeyChar == ' '){
      MessageBox.Show(richTextBox1.Text.Substring(startIndex, richTextBox1.SelectionStart - startIndex));          
      newStart = true;
   }                   
}

The important thing to notice here is the order of the events:

  1. KeyDown
  2. KeyPress
  3. SelectionChanged
  4. KeyUp

Upvotes: 1

ismellike
ismellike

Reputation: 629

You can try something like this

    RichTextBox richTextBox = new RichTextBox();
    string lastWord;
    private void KeyPress(object sender, KeyPressEventArgs e)
    {
        if (e.KeyChar == ' ')
        {
            lastWord = richTextBox.Text.Split(' ')[richTextBox.Text.Split(' ').Count() - 2];
        }
    }

I can't exactly test it right now, but it should give you a strong idea on how to do what you want.

EDIT::: Sorry about that, try this instead

    string lastword;
    private void KeyPress(object sender, KeyPressEventArgs e)
    {
        if (e.KeyChar == ' ')
        {
            lastword = ReadBack(rtb.SelectionStart);
        }
    }
    private string ReadBack(int start)
    {
        string builder = "";
        for (int x = start; x >= 0; x--)
        {
            Char c = rtb.Text[x];
            if (c == ' ')
                break;
            builder += c;
        }
        Array.Reverse(builder.ToArray());
        return builder;
    }

Upvotes: 1

Pierre-Luc Pineault
Pierre-Luc Pineault

Reputation: 9191

Okay screw my first answer, that should be better :

private void richTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == ' ')
    {
        int wordEndPosition = richTextBox1.SelectionStart;
        int currentPosition = wordEndPosition;

        while (currentPosition > 0 && richTextBox1.Text[currentPosition - 1] != ' ')
        {
            currentPosition--;
        }

        string word = richTextBox1.Text.Substring(currentPosition, wordEndPosition - currentPosition);
    }
}

SelectionStart gets the current caret position. SelectionStart is normally used to know where the user's text selection (the 'blue highlighted text') starts and ends. However, even when there's no selection, it still works to get the current caret position.

Then, to get the word entered, it goess backwards until it finds a space (or index 0, for the first word).

So you get the word with a little Substring, and currentPosition holds the index of your word.

Works for words everywhere, but it have one weakness : If instead of putting the caret after 'quick ' and entering "brown SPACE" the user places the caret at 'quick' and types "SPACE brown" well, it's not possible to detect it currently.

Upvotes: 6

Related Questions