Почему PreviewTextInput не обрабатывает пробелы?

Я обрабатываю событие PreviewTextInput в своем окне для обработки проверок с устройства чтения магнитных карт. Я обрабатываю событие в окне, так что не имеет значения, какой именно элемент управления сосредоточен.

Как только обработчик определит, что салфетка запущена (вводится символ "%" или ";" ), он обрабатывает все события, пока салфетка не будет завершена. Эта система, как правило, работает довольно хорошо, с несколькими важными исключениями:

Когда символ пробела (и, возможно, символ \n) вводится из считывателя, они не обрабатываются PreviewTextInput, а отправляются непосредственно в любой элемент управления. Как ни странно, обработчик получает символы \r. Это вызывает нежелательное поведение.

Я хочу, чтобы захватить все ключевые события на уровне окна и иметь возможность обрабатывать их, если захочу. Я попробовал PreviewKeyDown и нашел его немного громоздким в использовании и получить значения char. PreviewTextInput гораздо приятнее, потому что я могу просто прочитать свойство Text.

Есть ли причина, по которой PreviewTextInput не обрабатывает определенные символы? Есть ли сопоставимый метод для получения всех событий, включая пробелы?

Ответ 1

Я нашел какое-то объяснение в этот вопрос форума WPF:

Поскольку некоторые IME будут обрабатывать пробельные нажатия клавиш как часть процесса составления текста, то почему он ловит Avalon для сообщения правильного композитного текста через событие TextInput.

И еще несколько сведений из Документация MSDN события TextInput:

... Для ввода с клавиатуры WPF сначала отправляет соответствующие события KeyDown/KeyUp. Если эти события не обрабатываются, а ключ является текстовым (а не управляющим ключом, например направленными стрелками или функциональными клавишами), то возникает событие TextInput. Между событиями KeyDown/KeyUp и TextInput не всегда есть простое взаимно однозначное сопоставление, поскольку несколько нажатий клавиш могут генерировать один символ ввода текста, а одиночные нажатия клавиш могут генерировать многосимвольные строки. Это особенно актуально для таких языков, как китайский, японский и корейский языки, которые используют Редакторы методов ввода (IME) для генерации тысяч возможных символов в соответствующих алфавитах.

Когда WPF отправляет событие KeyUp/KeyDown, Key устанавливается в Key.System, если нажатия клавиш могут стать частью события TextInput (например, если нажата клавиша ALT + S). Это позволяет использовать код в обработчике событий KeyDown для проверки Key.System и, если найден, оставить обработку для обработчика впоследствии поднятого события TextInput. В этих случаях различные свойства аргумента TextCompositionEventArgs могут использоваться для определения исходных нажатий клавиш. Аналогично, если IME активен, Key имеет значение Key.ImeProcessed, а ImeProcessedKey дает исходное нажатие клавиши или нажатия клавиш.

Кстати, вот два связанных вопроса:

Ответ 2

Обходным решением, которое я нашел, является привязка PreviewKeyDown вместо PreviewTextInput. К сожалению, для этого подхода требуется гораздо больше проблем, чтобы получить конкретную char для какой кнопки они нажали. Самый надежный способ, который я нашел, был в этом вопросе. Это кажется довольно громоздким, поскольку то, что я чувствую, должно быть довольно простым. У кого-нибудь есть лучший способ сделать это?