【问题标题】:How do I stop WPF KeyDown events from bubbling up from certain contained controls (such as TextBox)?如何阻止 WPF KeyDown 事件从某些包含的控件(例如 TextBox)冒泡?
【发布时间】:2014-09-12 10:06:42
【问题描述】:

我的程序很大,并且使用 WPF,我想要一个使用“R”的全局快捷键,没有修饰符。
有许多控件,例如 TextBox、ListBox、ComboBox 等,它们都在控件本身内部使用字母,这很好 - 这对我来说是正确的。
但是 - 我想让 KeyDown 事件不会冒泡到主窗口,例如,只要用户在 TextBox 中键入字母“R”,它就会触发快捷方式。
理想情况下,我希望能够做到这一点,而不必指定(并执行 if-then 逻辑)每个可能接收正常字母按键的控件实例/类型(不仅仅是 TextBox 控件,尽管它们是最严重的违规者)。

【问题讨论】:

    标签: c# wpf event-bubbling


    【解决方案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 上的 KeyDownPreviewKeyDown 事件中设置 e.Handled = true,而不是单独的控件。无论如何,我认为OriginalSource 是您答案的关键。 (我发誓这不是双关语)。

    【讨论】:

    • e.Handled 设置为true 绝对是正确的方法。第一个提议的解决方案实际上并不能防止冒泡。
    • @MathiasLykkegaardLorenzen 我很感兴趣,它是如何防止冒泡的?
    • 通过“第一个提出的解决方案”我指的是他自己的代码,当e.OriginalSourceWindow 时,它基本上只是应用逻辑。我指的不是你的代码,@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 是正确的,可以防止输入任何文本。
    • 另外,我必须为每个可能接受文本输入的控件(当前和未来)添加一个事件处理程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 2023-03-31
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多