none
如何在KeyDown设置e.handled = true后,仍能响应绑定命令 RRS feed

  • 问题

  • 你好,我在研究CommandBinding时,发现若绑定命令控件的KeyDown事件中设置了e.handled = true后,帮定命令的手势操作将无效。请问如何解决该问题。

    代码如下:

    XAML:

    <Window x:Class="Commands.CustomCommand"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Commands" Height="300" Width="300"
        xmlns:local="clr-namespace:Commands"
        >
      <Window.CommandBindings>
        <CommandBinding Command="local:DataCommands.Requery"  Executed="RequeryCommand"/>
      </Window.CommandBindings>
      <Grid>
        <Button Margin="5" Command="local:DataCommands.Requery" KeyDown="Button_KeyDown">Requery</Button>      
        </Grid>
    </Window>

    c#:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    namespace Commands
    {
        /// <summary>
        /// Interaction logic for CustomCommand.xaml
        /// </summary>
        public partial class CustomCommand : System.Windows.Window
        {
            public CustomCommand()
            {
                InitializeComponent();
            }
            private void RequeryCommand(object sender, ExecutedRoutedEventArgs e)
            {
                MessageBox.Show("Requery");
            }
            private void Button_KeyDown(object sender, KeyEventArgs e)
            {
                MessageBox.Show("Key Down");
                e.Handled = true;
            }
        }
        public class DataCommands
        {
            private static RoutedUICommand requery;
            static DataCommands()
            {
                InputGestureCollection inputs = new InputGestureCollection();
                inputs.Add(new KeyGesture(Key.R, ModifierKeys.Control, "Ctrl+R"));
                inputs.Add(new KeyGesture(Key.R, ModifierKeys.Alt, "Alt+R"));
                inputs.Add(new KeyGesture(Key.F5, ModifierKeys.None, "Alt+R"));
                //inputs.Add(new KeyGesture(Key.R, ModifierKeys.None, "None+R"));
                requery = new RoutedUICommand("Requery", "Requery", typeof(DataCommands), inputs);
            }
             
            public static RoutedUICommand Requery
            {
                get { return requery; }
            }
        }
    }

    2014年7月17日 6:57

答案

  • 你好,

    对于Button控件,你在KeyDown事件中设置e.handled = true,后续事件处理会被截断,所以绑定的命令无法执行。

    在这里一个解决方案是在Button KeyDown事件e.Handled = true;之后遍历所有CommandBindings中的InputGesture,这样会正常执行:

    private void RequeryCommand(object sender, ExecutedRoutedEventArgs e)
    {
                MessageBox.Show("Requery");
    }
    
    private void Button_KeyDown(object sender, KeyEventArgs e)
    {
                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;
                            }
                        }
                    }
                }
    }

    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • 已标记为答案 wtw_Kevin 2014年7月21日 3:59
    2014年7月18日 6:59
    版主

全部回复

  • 你好,

    对于Button控件,你在KeyDown事件中设置e.handled = true,后续事件处理会被截断,所以绑定的命令无法执行。

    在这里一个解决方案是在Button KeyDown事件e.Handled = true;之后遍历所有CommandBindings中的InputGesture,这样会正常执行:

    private void RequeryCommand(object sender, ExecutedRoutedEventArgs e)
    {
                MessageBox.Show("Requery");
    }
    
    private void Button_KeyDown(object sender, KeyEventArgs e)
    {
                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;
                            }
                        }
                    }
                }
    }

    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • 已标记为答案 wtw_Kevin 2014年7月21日 3:59
    2014年7月18日 6:59
    版主
  • 试了下可行,很有帮助,谢谢

    2014年7月21日 3:59