c# - 在 WPF RichTextBox 中快速键入会混淆事件
问题描述
我正在尝试在 WPF 中实现一个简单的自动更正功能RichTextBox
。特别是,其中两个功能是 1.) 缩写扩展(当您键入“idk”和一个空格时,“idk”被替换为“我不知道”)和 2.)在末尾添加句点一条线。我正在通过PreviewKeyDown
事件来实现这一点,检测何时出现单词分隔符(用于缩写扩展)或回车(用于添加句点)。它在大多数情况下都有效,但我在打字速度极快时看到了一种奇怪的行为。似乎可以在后续键的事件之后将字符插入到文本中。PreviewKeyDown
例如,假设您想输入缩写“idk”,然后输入回车,那么您将得到“我不知道”这一行。如果您键入“id”,然后键入“k”,然后ENTER快速连续,键的PreviewKeyDown
事件会在“k”插入文本之前发生。所以事件代码看不到要扩展的完整“idk”缩写——它只看到“id”。然后它将句点放在“id”的末尾(由于密钥)。之后最后将“k”插入到文本中,因此结果是“id.k”ENTERPreviewKeyDown
ENTER
这是一个非常奇特的案例。如果您几乎不同时按“k”和ENTER键,则不会发生。我有一个演示应用程序,我在其中使用 WPF 密钥模拟器库来立即发送字符。该应用程序在这里:https ://github.com/garzooma/RichTextBoxDemo 。密钥模拟器库在这里https://archive.codeplex.com/?p=wpfsendkeys]。
我已经尝试设置标志来延迟第二次击键的处理,但这只会让一切都挂起——第一次击键永远不会被处理。
PreviewTextInput
在我的演示应用程序中,我尝试了一个 hack,其中代码通过在事件处理程序中设置一个标志并在处理程序中清除它来检测在后续按键发生之前何时未处理字符TextChanged
。当PreviewKeyDown
代码看到标志时,我设置了一个在后续TextChanged
事件中处理的 Action 变量。这似乎有效。但我希望找到一种方法来避免问题发生。
基本代码是:
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(".");
}
}
解决方案
推荐阅读
- java - 如何在java上将bad_request设置为异常
- css - Angular 12 警告:由于选择器错误,跳过了 1 条规则::host-context(.isDarkTheme) -> 不匹配的伪类:host-context
- ansible-awx - 如何从 AWX 迁移到 Ansible Tower?
- microsoft-graph-api - 无法通过逻辑应用程序或图形 API 更新现有服务原则中的证书
- keras - 在 Keras 中实现 Python LSTM 的问题
- jquery - 从 Django 中的 Annotate 获取多个字段
- spring - 如何在代码底部找到自动装配的 bean
- react-native - 自定义选项卡导航器在屏幕中重叠(React-Native)
- batch-file - WinSCP FTP 脚本的时间戳日志文件
- mongodb - 如何在 MongoDb 文档中计算几个/所有相同的字符串?