WPF TextBox.KeyDown事件捕获回车键时未触发如何解决
问题根因
两个核心问题导致逻辑不生效:
- 回车键判断分支无法命中:WPF
TextBox控件内部会默认处理回车键事件,将事件标记为已处理,冒泡阶段的KeyDown事件不会响应用户自定义的逻辑,断点自然无法触发。 - 传入变量修改字号不生效:通常是两个原因导致:一是直接用
Convert.ToDouble()转换输入值时,非合法输入会抛出异常中断逻辑;二是RichTextBox无选中文本时,rtb.Selection对应的范围是空范围,修改操作不会作用到任何文本上。
实现方案
- 将字号输入框的按键监听事件从
KeyDown替换为PreviewKeyDown。PreviewKeyDown是隧道路由事件,会在控件内部处理按键前触发,不会被控件默认逻辑拦截。 - 捕获到回车键后,先将事件标记为已处理,屏蔽TextBox默认的回车响应。
- 安全转换输入框内的字号值,过滤非法输入。
- 区分RichTextBox选中状态:存在选中文本时仅修改选中部分字号,无选中文本时修改整个文档的字号。
对应的后台代码如下:
private void FontSizeBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) { if (e.Key == Key.Return) { e.Handled = true; // 安全转换字号输入值 if (!double.TryParse(FontSizeBox.Text.Trim(), out double fontSize) || fontSize <= 0) { // 可在此处添加非法输入提示,例如清空输入、恢复上次有效值 return; } TextRange targetRange; if (rtb.Selection.IsEmpty) { // 无选中文本时,操作范围覆盖整个文档 targetRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd); } else { // 有选中文本时仅操作选中范围 targetRange = new TextRange(rtb.Selection.Start, rtb.Selection.End); } targetRange.ApplyPropertyValue(TextElement.FontSizeProperty, fontSize); // 可选操作:修改完成后将焦点切回RichTextBox,方便连续编辑 rtb.Focus(); } }
记得同步修改XAML中字号输入框的事件绑定,把原来的KeyDown事件替换为PreviewKeyDown:
<TextBox x:Name="FontSizeBox" Width="60" PreviewKeyDown="FontSizeBox_PreviewKeyDown"/>
补充说明:测试阶段用字面量
18生效,是因为字面量本身是合法的double类型值,不存在转换失败问题,且当时没有加按键判断,逻辑是直接执行的,不存在事件被拦截的情况。
内容的提问来源于stack exchange,提问作者TheWaterWave222
相关产品推荐
相关产品推荐

