WPF:如何防止控件窃取按键手势? [英] WPF: How to prevent a control from stealing a key gesture?

查看:27
本文介绍了WPF:如何防止控件窃取按键手势?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 WPF 应用程序中,我想将输入手势附加到命令,以便输入手势在主窗口中全局可用,无论哪个控件具有焦点.

In my WPF application I would like to attach an input gesture to a command so that the input gesture is globally available in the main window, no matter which control has the focus.

在我的情况下,我想将 Key.PageDown 绑定到命令,但是,一旦某些控件收到焦点(例如 TextBox 或 TreeView 控件),这些控件就会收到键事件并且命令不再被触发.这些控件没有定义特定的 CommandBindingsInputBindings.

In my case I would like to bind Key.PageDown to a command, however, as soon as certain controls receive the focus (e.g. a TextBox or TreeView control), these controls receive the key events and the command is no longer triggered. These controls have no specific CommandBindings or InputBindings defined.

这就是我定义输入手势的方式:

This is how I define my input gesture:

XAML:

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300" >
    <StackPanel>
        <TreeView>
            <TreeViewItem Header="1">
                <TreeViewItem Header="1.1"></TreeViewItem>
                <TreeViewItem Header="1.2"></TreeViewItem>
            </TreeViewItem>
            <TreeViewItem Header="2" ></TreeViewItem>
        </TreeView>
        <TextBox />
        <Label Name="label1" />
    </StackPanel>
</Window>

代码:

using System;
using System.Windows;
using System.Windows.Input;

public static class Commands
{
    private static RoutedUICommand _myCommand;

    static Commands()
    {
        _myCommand = new RoutedUICommand("My Command",
            "My Command",
            typeof(Commands),
            new InputGestureCollection()
                {
                    new KeyGesture(Key.PageDown, ModifierKeys.None)
                });
    }

    public static ICommand MyCommand
    {
        get { return _myCommand; }
    }
}

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        CommandBinding cb = new CommandBinding();
        cb.Command = Commands.MyCommand;
        cb.Executed += new ExecutedRoutedEventHandler(cb_Executed);
        cb.CanExecute += new CanExecuteRoutedEventHandler(cb_CanExecute);
        this.CommandBindings.Add(cb);
    }

    void cb_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
    }

    void cb_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        this.label1.Content = string.Format("My Command was executed {0}", DateTime.Now);
    }
}

我已经尝试捕获窗口的 PreviewKeyDown 事件并将其标记为已处理这没有达到预期的效果.我还将 Focusable 属性设置为 false.这对 TextBox 控件有帮助,但对 TreeView 没有帮助(并且会产生不希望的效果,即 TextBox 不再可以编辑,因此它不是我的解决方案).

I already tried catching the window's PreviewKeyDown event and marking it as handled This had not the desired effect. I also set the Focusable property to false. This helped for TextBox controls, but not for the TreeView (and has the unwanted effect, that the TextBox no longer can be edited so it is not a solution for me).

所以我的问题是如何定义在主窗口中随处可用的键盘快捷键?

So my question is how can I define a keyboard shortcut that works everywhere in the main window?

推荐答案

以下解决方法似乎具有使命令全局到窗口的预期效果;但是,我仍然想知道在 WPF 中是否没有更简单的方法:

The following workaround seems to have the desired effect of having the command global to the window; however, I still wonder whether there is no easier way to do this in WPF:

private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
    foreach (InputBinding inputBinding in this.InputBindings)
    {
        KeyGesture keyGesture = inputBinding.Gesture as KeyGesture;
        if (keyGesture != null && keyGesture.Key == e.Key && keyGesture.Modifiers == Keyboard.Modifiers)
        {
            if (inputBinding.Command != null)
            {
                inputBinding.Command.Execute(0);
                e.Handled = true;
            }
        }
    }

    foreach (CommandBinding cb in this.CommandBindings)
    {
        RoutedCommand command = cb.Command as RoutedCommand;
        if (command != null)
        {
            foreach (InputGesture inputGesture in command.InputGestures)
            {
                KeyGesture keyGesture = inputGesture as KeyGesture;
                if (keyGesture != null && keyGesture.Key == e.Key && keyGesture.Modifiers == Keyboard.Modifiers)
                {
                    command.Execute(0, this);
                    e.Handled = true;
                }
            }
        }
    }
}

}

这篇关于WPF:如何防止控件窃取按键手势?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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