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

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

问题描述

以下情况。我有一个用五个键绑定的用户控件。当TextBox有焦点的时候,UserControl的keybindings会停止触发。



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

 < UserControl.InputBindings> 
< KeyBinding Key =PageDownModifiers =ControlCommand ={Binding NextCommand}>< / KeyBinding>
< KeyBinding Key =PageUpModifiers =ControlCommand ={Binding PreviousCommand}>< / KeyBinding>
< /UserControl.InputBindings>
< TextBox Text ={Binding FilterText,UpdateSourceTrigger = PropertyChanged}>
< TextBox.InputBindings>
将键绑定手势= 输入 命令= {结合的RelativeSource = {的RelativeSource AncestorType = {X:类型用户控件}},路径= DataContext.FilterCommand} >< /键绑定>
< /TextBox.InputBindings>
< / TextBox>

似乎功能键( F1 etc)和 / kbd> + [key] 做功。我假设 CTRL SHIFT 修饰符以某种方式阻止事件冒泡到UserControl。

解决方案

一些输入绑定工作的原因是,TextBox控件捕获并处理一些键绑定。例如,它处理粘贴的 CTRL + V CTRL + 首页另一方面,其他组合键(如 CTRL + F3 )不会被TextBox处理,所以它们会冒泡。



如果您只想禁用TextBox的输入绑定,那很简单 - 您可以使用 ApplicationCommands.NotACommand 命令会禁用默认行为。例如,在以下情况下,粘贴 CTRL + V 将被禁用: > <文本框>
< TextBox.InputBindings>
< KeyBinding Key =VModifiers =ControlCommand =ApplicationCommands.NotACommand/>
< /TextBox.InputBindings>
< / TextBox>

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



我写了一个基本的行为来实现这个功能,让你开始:

<预类= 郎-CS prettyprint-越权> 公共类InputBindingsBehavior
{
公共静态只读的DependencyProperty TakesInputBindingPrecedenceProperty =
DependencyProperty.RegisterAttached( TakesInputBindingPrecedence,typeof(bool),typeof(InputBindingsBehavior),新的UIPropertyMetadata(false,OnTakesInputBindingPrecedenceChanged));
$ b $ public static bool GetTakesInputBindingPrecedence(UIElement obj)
{
return(bool)obj.GetValue(TakesInputBindingPrecedenceProperty);


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

私有静态无效OnTakesInputBindingPrecedenceChanged(的DependencyObject d,DependencyPropertyChangedEventArgs E)
{
((的UIElement)d).PreviewKeyDown + =新KeyEventHandler(InputBindingsBehavior_PreviewKeyDown);


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

变种foundBinding = uielement.InputBindings
.OfType<键绑定>()
.FirstOrDefault(KB => kb.Key == e.Key&安培;&安培; kb的。修饰符== e.KeyboardDevice.Modifiers);

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




code
$ b

 < UserControl local:InputBindingsBehavior.TakesInputBindingPrecedence =True> 
< UserControl.InputBindings>
< KeyBinding Key =HomeModifiers =ControlCommand ={Binding MyCommand}/>
< /UserControl.InputBindings>
< 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>

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.

解决方案

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.

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>

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);
            }
        }
    }
}

Usage:

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

Hope this helps.

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

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