Как выделить каждое слово в тексте поочередно по нажатию комбинации клавиш?

У меня есть текст в RichTextBox, Хочу по нажатию на комбинацию клавиш поочередно выделить все слова текста (символы от пробела до пробела, знака препинания, или конца текста). Для этого добавил KeyEventHandlerи написал такой код в его обработчике:

 private void hotKeys(object sender, KeyEventArgs e) {

  if (e.Alt && e.KeyCode == Keys.Right) {
     if (richTextBox.Focused)
     {
     richTextBox.SelectionLength = richTextBox.Text.Length - richTextBox.SelectionStart;
     string text = richTextBox.SelectedText;
     int endOfWord = Regex.Match(text, @"\s+").Index;
     richTextBox.SelectionLength = endOfWord;
                    
     } 
  }
}

Он правильно выделяет символы от пробела до пробела в тексте, но есть одна проблема: перед следующим вызовом метода надо снимать выделение со слова вручную. Покажу на скрине. Допустим, я вызываю метод первый раз:

введите сюда описание изображения

Если сразу же нажать комбинацию клавиш второй раз, то выделится то же слово "Слово1", но если вручную, допустим стрелкой, передвинуть каретку к началу следующего слова и вызвать hotKeys то метод выделит его: введите сюда описание изображения

Вопрос: как сделать так, чтобы можно было вызывать метод подряд. Или как передвинуть каретку после выделения текста, но при этом выделение оставить? У меня была мысль добавить в код, что-то типа:

if (e.Alt && e.KeyCode == Keys.Right) {
                if (richTextBox.Focused)
                {
                    richTextBox.SelectionLength = richTextBox.Text.Length - richTextBox.SelectionStart;
                    string text = richTextBox.SelectedText;
                    int endOfWord = Regex.Match(text, @"\s+").Index;
                    richTextBox.SelectionLength = endOfWord;
                    // После выделения передвигаем каретку
                    richTextBox.SelectionStart = endOfWord;
                    richTextBox.SelectionLength = 0;
                } 
            }
        }

Но тогда каретка "прыгает" то в конец то в начало первого слова при каждом вызове метода, а выделения нет: введите сюда описание изображения введите сюда описание изображения

Правка:

У RichTextBox по умолчанию есть перемещение каретки с ctrl. Вот оно введите сюда описание изображения

Как видно на скрине каретка передвинулась к началу "слово2". Я хочу реализовать такое поведение: Нажали на ctrl+Right первый раз: введите сюда описание изображения

Затем второй: введите сюда описание изображения

(Выделил текст мышкой для демонстрации)


Ответы (2 шт):

Автор решения: Iron Man

Если я правильно понял задачу то этот код должен работать

int start = 0;
int lengthminus = 0;
//Событие получения фокуса
private void OnFocus(object sender, EventArgs e) 
{
   richTextBox.SelectionStart=0;
   start=0;
   lengthminus = 0;
}
private void hotKeys(object sender, KeyEventArgs e) {

  if (e.Alt && e.KeyCode == Keys.Right) {
     if (e.Alt && e.KeyCode == Keys.Right)
     {
        if (richTextBox1.Focused)
        {
           string target = " ,.:;";//символы которые будут концом выделения
           char[] anyOf = target.ToCharArray();
           if (start + 1 < richTextBox1.Text.Length)
           {
              int length = richTextBox1.Text.IndexOfAny(anyOf, start + 1);//длина для выделения
              int length1 = length;
              length -= lengthminus;
              if (lengthminus < richTextBox1.Text.Length)
              {
                 lengthminus = length1;
                 if (length < 0)
                 {
                    length = richTextBox1.Text.Length - start;
                 }
                 richTextBox1.SelectionStart = start;
                 richTextBox1.SelectionLength = length;
                 start += length;
              }
           }
        }
     }
  }
} 
→ Ссылка
Автор решения: aepot

Привяжите эти два обработчика к RichTextBox событиям KeyDown и KeyUp соответственно.

private int selectionStart = 0;

private void RichTextBox1_KeyUp(object sender, KeyEventArgs e)
{
    if (!e.Shift && e.Control && (e.KeyCode == Keys.Right || e.KeyCode == Keys.Left))
    {
        if (e.KeyCode == Keys.Right)
        {
            int pos = richTextBox1.SelectionStart;
            richTextBox1.SelectionStart = selectionStart;
            richTextBox1.SelectionLength = pos - selectionStart;
        }
        else
            richTextBox1.SelectionLength = selectionStart - richTextBox1.SelectionStart;
    }
}

private void RichTextBox1_KeyDown(object sender, KeyEventArgs e)
{
    if (!e.Shift && e.Control && (e.KeyCode == Keys.Right || e.KeyCode == Keys.Left))
    {
        if (e.KeyCode == Keys.Right)
            richTextBox1.SelectionStart += richTextBox1.SelectionLength;
        selectionStart = richTextBox1.SelectionStart;
        richTextBox1.SelectionLength = 0;
    }
}

Либо в дизайнере - выбрать RichTextBox, нажать кнопочку с молнией, выбрать нужное событие из перечисленных выше, и выбрать обработчик из выпадающего списка, либо через вставку вот такого кода в Form.Load.

private void Form1_Load(object sender, EventArgs e)
{
    richTextBox1.KeyDown += RichTextBox1_KeyDown;
    richTextBox1.KeyUp += RichTextBox1_KeyUp;
}

А свой обработчик hotKeys при этом отключите, иначе может не сработать.

→ Ссылка