WPF路由命令有时仅触发

时间:2011-02-24 21:42:32

标签: wpf canvas focus routedcommand

我有一些RoutedCommands用于控制-A,复制粘贴之类的命令,它们都可以正常工作。 然后我添加了4个routedcommands来使用arrowkeys在画布中左右移动对象,它们有时会工作,有时则不会。起初我认为它是Canvas上的Focus问题,但我发现同时,所有其他路由命令(如control-A)都可以,但是arrowkeys却没有。 我真的不知道这里发生了什么,它们是相同的路由命令,具有不同的变量名称,为什么100%的时间工作,1只工作50%的时间?

Working RoutedCommand:

_bindings.Add(new CommandBinding(DesignerCanvas.SelectAll, SelectAll_Executed));
SelectAll.InputGestures.Add(new KeyGesture(Key.A, ModifierKeys.Control));

private void SelectAll_Executed(object sender, ExecutedRoutedEventArgs e)
{
    SelectionService.SelectAll();
}

RoutedCommand发生故障:

_bindings.Add(new CommandBinding(DesignerCanvas.MoveDown, MoveDown_Executed));
MoveDown.InputGestures.Add(new KeyGesture(Key.Down));

private void MoveDown_Executed(object sender, ExecutedRoutedEventArgs e)
{
    e.Handled = true;
    var selectedItems = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
                            select item;

    if (selectedItems.Count() > 0)
    {
        for (int i = 0; i < selectedItems.Count(); i++)
            selectedItems.ElementAt(i).Top += Option.OptionSingleton.Sensitivity;
    }
}

发生故障的RoutedCommand有时不会触发,特别是在我打开其他窗口并返回画布后,它将停止触发,而其他路由命令不受影响。是什么导致了这种奇怪的行为?

3 个答案:

答案 0 :(得分:2)

您可以使用非常具有包容性的类事件处理程序来跟踪事件的路径:

EventManager.RegisterClassHandler(typeof(FrameworkElement), CommandManager.CanExecuteEvent, 
     new CanExecuteRoutedEventHandler((s, e) => Debug.WriteLine("CanExecute: " + s)), true);
EventManager.RegisterClassHandler(typeof(FrameworkElement), CommandManager.ExecutedEvent, 
     new CanExecuteRoutedEventHandler((s, e) => Debug.WriteLine("Executed:" + s)), true);
EventManager.RegisterClassHandler(typeof(FrameworkElement), CommandManager.ExecutedEvent, 
     new CanExecuteRoutedEventHandler((s, e) => Debug.WriteLine("KeyDown:" + s)), true);

在您的情况下,KeyDown可能会在到达命令绑定之前被处理,或者CanExecute事件可能由于其他原因而无法到达。

希望这可以帮助您调试问题

答案 1 :(得分:1)

这可能是因为您使用的密钥是“向下”键。我怀疑如果你使用了不同的密钥,那就可以了。

某些控件会使用箭头键和pageup / pagedown键。例如,TextBox就是这样做的。如果您的画布在滚动查看器中,则滚动查看器可能正在吃它。

有两种解决方法:

  1. 向正在吃主要手势的控件添加绑定。
  2. 处理Canvas的KeyPreview(或正在进行击键的控件的任何父级)并从那里执行命令。
  3. this question的答案显示了如何在不为每个命令的KeyPreview处理程序编写特定代码的情况下执行#2。

答案 2 :(得分:1)

事实证明这是一个焦点问题,我只是在鼠标进入时将焦点设置到画布上,现在它已经修复了。谢谢大家的回答。