如何阻止 WPF KeyDown 事件从某些包含的控件(例如 TextBox)冒泡?
Posted
技术标签:
【中文标题】如何阻止 WPF KeyDown 事件从某些包含的控件(例如 TextBox)冒泡?【英文标题】:How do I stop WPF KeyDown events from bubbling up from certain contained controls (such as TextBox)? 【发布时间】:2014-09-12 10:06:42 【问题描述】:我的程序很大,并且使用 WPF,我想要一个使用“R”的全局快捷键,没有修饰符。 有许多控件,例如 TextBox、ListBox、ComboBox 等,它们都在控件本身内部使用字母,这很好 - 这对我来说是正确的。 但是 - 我想让 KeyDown 事件不会冒泡到主窗口,例如,只要用户在 TextBox 中键入字母“R”,它就会触发快捷方式。 理想情况下,我希望能够做到这一点,而不必指定(并执行 if-then 逻辑)每个可能接收正常字母按键的控件实例/类型(不仅仅是 TextBox 控件,尽管它们是最严重的违规者)。
【问题讨论】:
【参考方案1】:只需检查 Window 上的 KeyDown
事件处理程序中的 OriginalSource
是什么:
private void Window_KeyDown(object sender, KeyEventArgs e)
if(e.OriginalSource is TextBox || e.OriginalSource is DateTimePicker) //etc
e.Handled = true;
return;
或者,如果您正在使用 InputBindings,请尝试在您的 Window 上的 KeyDown
或 PreviewKeyDown
事件中设置 e.Handled = true
,而不是单独的控件。无论如何,我认为OriginalSource
是您答案的关键。 (我发誓这不是双关语)。
【讨论】:
将e.Handled
设置为true
绝对是正确的方法。第一个提议的解决方案实际上并不能防止冒泡。
@MathiasLykkegaardLorenzen 我很感兴趣,它是如何防止冒泡的?
通过“第一个提出的解决方案”我指的是他自己的代码,当e.OriginalSource
是Window
时,它基本上只是应用逻辑。我指的不是你的代码,@lll。事实上,我对你的代码投了赞成票。
这不是一个坏主意——但是,它忽略了在窗口不是主要焦点时可能按下的任何快捷键,这是很常见的情况。
@redroze:对不起,当窗口不是主要焦点时,我不明白你的意思?我不希望您指的是其他窗口。但是如果 KeyDown 事件发生在 Window 中的某个地方,它会冒泡到处理程序,除非被处理,对吧?【参考方案2】:
当您处理KeyDown
事件时有一个事件,它应该传递给您一个KeyEventArgs
。从那里您可以将Handled
设置为true,这样它就不会冒泡。
样本
private void TextBoxEx_KeyAction(object sender, KeyEventArgs e)
e.Handled = true;
【讨论】:
这也会阻止 TextBox 实际输入文本,因为它会阻止 TextBox 处理文本合成事件。 嗯,不,除非您覆盖一个事件并且不调用 base.OnKeyPressed(e);那是OnKeyPressed
那么是的,它不会处理输入文本。
@Ill:那我一定是误解了你在做什么。创建一个带有TextBox
的空项目,并添加一个KeyDown
事件处理程序,只包含e.Handled = true
。它不会接受任何文本。
Troels 是正确的,可以防止输入任何文本。
另外,我必须为每个可能接受文本输入的控件(当前和未来)添加一个事件处理程序。以上是关于如何阻止 WPF KeyDown 事件从某些包含的控件(例如 TextBox)冒泡?的主要内容,如果未能解决你的问题,请参考以下文章