Быстрая печать в WPF RichTextBox перемешивает события - PullRequest
0 голосов
/ 20 сентября 2019

Я пытаюсь реализовать простую функцию автозамены в WPF RichTextBox.В частности, две функции: 1.) расширение аббревиатуры (когда вы вводите «idk» и пробел, «idk» заменяется на «я не знаю») и 2.) добавление точки в концелиния.Я реализую это через событие PreviewKeyDown, определяя, когда происходит разделитель слов (для расширения аббревиатуры) или возврат каретки (для добавления точки).Это работает по большей части, но я вижу странное поведение при наборе очень быстро.Кажется, что вставка символа в текст может произойти после события PreviewKeyDown для последующего ключа.

Например, предполагается, что вы хотите ввести аббревиатуру "idk" с последующим возвратом каретки, так что в итоге вы получите строку "Я не знаю".Если вы введете «id», а затем «k» и «[ENTER]» в быстрой последовательности, событие PreviewKeyDown для клавиши [ENTER] наступает за до , когда «k» вставляется в текст.Таким образом, код события PreviewKeyDown не видит полную сокращенную аббревиатуру «idk» - он просто видит «id».И затем он ставит точку в конце «id» (из-за клавиши [ENTER]).Наконец, после этого в текст вставляется буква «k», и в результате получается «id.k»

. Это очень необычный случай.Если вы не нажимаете клавиши «k» и [ENTER] почти одновременно, это не происходит.У меня есть демо-приложение, в котором я использую библиотеку имитатора ключей WPF для отправки символов сразу после друг друга.Приложение здесь: https://github.com/garzooma/RichTextBoxDemo. Библиотека имитатора ключей здесь https://archive.codeplex.com/?p=wpfsendkeys].

Я пытался установить флаги, чтобы задержать обработку второго нажатия клавиши, но это просто все зависает- 1-е нажатие клавиши никогда не обрабатывается.

В моем демонстрационном приложении я пытаюсь взломать, когда код обнаруживает, когда символ не был обработан до того, как произойдет последующее нажатие клавиши, установив флаг в PreviewTextInputобработчик событий и очистка его в обработчике TextChanged.Когда код PreviewKeyDown видит флаг, я устанавливаю переменную Action, которая обрабатывается в последующем событии TextChanged.Это похоже на работу.Но я надеюсь найти способ, чтобы проблема не возникала.

Основной код:

private void PreviewKeyDownHandler(object sender, KeyEventArgs e)
{
  // See if we're at the end of a word
  if (delimiterKeys.Contains(e.Key))
  {
    string word = GetPrecedingText();
    // Is the word an abbreviation?
    if (abbreviations.ContainsKey(word.ToUpper()))
    {
      TextPointer pointer = textbox1.CaretPosition.GetPositionAtOffset(-word.Length);
      if (pointer.LogicalDirection == LogicalDirection.Backward)  // change direction, if needed
      {
        pointer = pointer.GetPositionAtOffset(0, LogicalDirection.Forward);
        textbox1.CaretPosition = pointer;
      }
      // replace abbreviation w/expansion
      pointer.DeleteTextInRun(word.Length);
      pointer.InsertTextInRun(abbreviations[word.ToUpper()]);
    }
    // Are we at the end of a line, and don't have a period?
    if (e.Key == Key.Enter && !word.EndsWith("."))
    {
      TextPointer pointer = textbox1.CaretPosition;
      if (pointer.LogicalDirection == LogicalDirection.Backward)  // change direction, if needed
      {
        pointer = pointer.GetPositionAtOffset(0, LogicalDirection.Forward);
        textbox1.CaretPosition = pointer;
      }
      pointer.InsertTextInRun(".");
    }
}
...