当 TextBox 具有焦点时,UserControl 中的 KeyBinding 不起作用 [英] KeyBinding in UserControl doesn't work when TextBox has the focus

查看:15
本文介绍了当 TextBox 具有焦点时,UserControl 中的 KeyBinding 不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下情况.我有一个带有五个键绑定的 UserControl.当 TextBox 获得焦点时,UserControl 的键绑定停止触发..

The following situation. I've got a UserControl with five keybindings. When the TextBox has the focus the keybindings of the UserControl stop firing..

有没有办法解决这个问题"?

Is there a way to fix this 'problem'?

<UserControl.InputBindings>
    <KeyBinding Key="PageDown" Modifiers="Control" Command="{Binding NextCommand}"></KeyBinding>
    <KeyBinding Key="PageUp" Modifiers="Control" Command="{Binding PreviousCommand}"></KeyBinding>
    <KeyBinding Key="End" Modifiers="Control"  Command="{Binding LastCommand}"></KeyBinding>
    <KeyBinding Key="Home" Modifiers="Control" Command="{Binding FirstCommand}"></KeyBinding>
    <KeyBinding Key="F" Modifiers="Control" Command="{Binding SetFocusCommand}"></KeyBinding>
</UserControl.InputBindings>
<TextBox Text="{Binding FilterText, UpdateSourceTrigger=PropertyChanged}">
    <TextBox.InputBindings>
        <KeyBinding Gesture="Enter" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl }}, Path=DataContext.FilterCommand}"></KeyBinding>
    </TextBox.InputBindings>
</TextBox>

似乎功能键(F1 等)和 ALT+[key] 可以工作.我认为 CTRLSHIFT 修饰符以某种方式阻止"事件冒泡到 UserControl.

It seems function keys (F1 etc) and ALT+[key] do work. I presume the CTRL and SHIFT modifiers are somehow 'blocking' the event from bubbling up to the UserControl.

推荐答案

有些输入绑定有效而有些无效的原因是 TextBox 控件捕获并处理一些键绑定.例如,它处理 CTRL+V 用于粘贴,CTRL+Home 用于转到文本的开头等其他组合键,例如 CTRL+F3 另一方面不被 TextBox 处理,因此它们会冒泡.

The reason some input bindings work and some don't is that the TextBox control catches and handles some key bindings. For example, it handles CTRL+V for paste, CTRL+Home for going to the beginning of the text, etc. Other key combinations such as CTRL+F3 on the other hand aren't handled by the TextBox, and so they will bubble up.

如果您只想禁用 TextBox 的输入绑定,那很简单 - 您可以使用 ApplicationCommands.NotACommand 命令,这将禁用默认行为.例如,在以下情况下,将禁用 CTRL+V 粘贴:

If you'd just wanted to disable the TextBox's input binding, that would be simple - you could use the ApplicationCommands.NotACommand command, which would disable the default behavior. For example, in the following case, pasting with CTRL+V will be disabled:

<TextBox>
    <TextBox.InputBindings>
        <KeyBinding Key="V" Modifiers="Control" Command="ApplicationCommands.NotACommand" />
    </TextBox.InputBindings>
</TextBox>

然而,让它冒泡到用户控件有点棘手.我的建议是创建一个将应用于 UserControl 的附加行为,注册到它的 PreviewKeyDown 事件,并在它们到达 TextBox 之前根据需要执行它的输入绑定.这将在执行输入绑定时优先考虑 UserControl.

However, making it bubble up to the user control is a bit trickier. My suggestion is to create an attached behavior that will be applied to the UserControl, register to its PreviewKeyDown event, and execute its input bindings as necessary before they reach the TextBox. This will give precedence to the UserControl when input bindings are executed.

我编写了一个实现此功能的基本行为来帮助您入门:

I wrote a basic behavior that achieves this functionality to get you started:

public class InputBindingsBehavior
{
    public static readonly DependencyProperty TakesInputBindingPrecedenceProperty =
        DependencyProperty.RegisterAttached("TakesInputBindingPrecedence", typeof(bool), typeof(InputBindingsBehavior), new UIPropertyMetadata(false, OnTakesInputBindingPrecedenceChanged));

    public static bool GetTakesInputBindingPrecedence(UIElement obj)
    {
        return (bool)obj.GetValue(TakesInputBindingPrecedenceProperty);
    }

    public static void SetTakesInputBindingPrecedence(UIElement obj, bool value)
    {
        obj.SetValue(TakesInputBindingPrecedenceProperty, value);
    }

    private static void OnTakesInputBindingPrecedenceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((UIElement)d).PreviewKeyDown += new KeyEventHandler(InputBindingsBehavior_PreviewKeyDown);
    }

    private static void InputBindingsBehavior_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        var uielement = (UIElement)sender;

        var foundBinding = uielement.InputBindings
            .OfType<KeyBinding>()
            .FirstOrDefault(kb => kb.Key == e.Key && kb.Modifiers == e.KeyboardDevice.Modifiers);

        if (foundBinding != null)
        {
            e.Handled = true;
            if (foundBinding.Command.CanExecute(foundBinding.CommandParameter))
            {
                foundBinding.Command.Execute(foundBinding.CommandParameter);
            }
        }
    }
}

用法:

<UserControl local:InputBindingsBehavior.TakesInputBindingPrecedence="True">
    <UserControl.InputBindings>
        <KeyBinding Key="Home" Modifiers="Control" Command="{Binding MyCommand}" />
    </UserControl.InputBindings>
    <TextBox ... />
</UserControl>

希望这会有所帮助.

这篇关于当 TextBox 具有焦点时,UserControl 中的 KeyBinding 不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆