Inconsistency in WPF command routing behavior depending on the UI focus state

后端 未结 3 563
暖寄归人
暖寄归人 2020-12-31 04:05

I have a RoutedUICommand command which can be fired in two different ways:

  • directly via ICommand.Execute upon a button click event;
3条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-31 04:24

    To elaborate on Noseratio's answer, RoutedCommand implements ICommand explicitly but also has its own Execute and CanExcute methods that take an additional target parameter. When you call RoutedCommand's explicit implementation of ICommand.Execute and ICommand.CanExcute, it will call its own version of these functions passing null as the target. If target is null, it will default to using Keyboard.FocusedElement. If target is still null after that (ie nothing has focus), the main body of the function is skipped and it just returns false. See the RoutedCommand source code on line 146 and 445.

    If you know the command is a RoutedCommand you can get around the focus issue by calling RoutedCommand.Execute(object, IInputElement) instead and provide a target. Here's a relevant extension method I wrote:

    public static void TryExecute(this ICommand command, object parameter, IInputElement target)
    {
        if (command == null) return;
    
        var routed = command as RoutedCommand;
        if (routed != null)
        {
            if (routed.CanExecute(parameter, target))
                routed.Execute(parameter, target);
        }
        else if (command.CanExecute(parameter))
            command.Execute(parameter);
    }
    

    For custom controls, I would typically call it like Command.TryExecute(parameter, this).

提交回复
热议问题