Keybinding a RelayCommand

后端 未结 6 696
有刺的猬
有刺的猬 2020-12-03 13:52

I\'m using the RelayCommand in my app. It\'s great for putting the code in the viewmodel, but how do I bind keystrokes to my command?

RoutedUICommand has its InputGe

相关标签:
6条回答
  • 2020-12-03 13:54

    The Command property of the KeyBinding class doesn't support data binding. This issue is going to be solved in .NET 4.0 and you should be able to see it in the coming .NET 4.0 Beta 2 version.

    0 讨论(0)
  • 2020-12-03 13:59

    I don't think you can do this from XAML, for exactly the reasons you describe.

    I ended up doing it in the code-behind. Although it's code, it's only a single line of code, and still rather declarative, so I can live with it. However, I'd really hope that this is solved in the next version of WPF.

    Here's a sample line of code from one of my projects:

    this.InputBindings.Add(new KeyBinding(
        ((MedicContext)this.DataContext).SynchronizeCommand,
        new KeyGesture(Key.F9)));
    

    SynchronizeCommand in this case is an instance of RelayCommand, and (obviously) F9 triggers it.

    0 讨论(0)
  • 2020-12-03 14:01

    You could subclass KeyBinding, add a CommandBinding dependency property that sets the Command property, and then add it to XAML like any other input binding.

    public class RelayKeyBinding : KeyBinding
    {
        public static readonly DependencyProperty CommandBindingProperty =
            DependencyProperty.Register("CommandBinding", typeof(ICommand), 
            typeof(RelayKeyBinding),
            new FrameworkPropertyMetadata(OnCommandBindingChanged));
        public ICommand CommandBinding
        {
            get { return (ICommand)GetValue(CommandBindingProperty); }
            set { SetValue(CommandBindingProperty, value); }
        }
    
        private static void OnCommandBindingChanged(
            DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var keyBinding = (RelayKeyBinding)d;
            keyBinding.Command = (ICommand)e.NewValue;
        }
    }
    

    XAML:

    <Window.InputBindings>
        <RelayKeyBinding 
            Key="PageUp" 
            CommandBinding="{Binding SelectPreviousLayerCommand}" />
    </Window.InputBindings>
    
    0 讨论(0)
  • 2020-12-03 14:09

    You can use the CommandReference class.

    Very elegant code and works like a charm.

    Take a look at: How do I associate a keypress with a DelegateCommand in Composite WPF?

    It works the same with RelayCommands, but it won't update your CanExecutes since the CommandReference doesn't use call CommandManager.RequerySuggested All you need to do to achieve automatic CanExecute reevaluation is do the following change inside the CommandReference class

    public event EventHandler CanExecuteChanged
    {
         add { CommandManager.RequerySuggested += value; }
         remove { CommandManager.RequerySuggested -= value; }
    }
    
    0 讨论(0)
  • 2020-12-03 14:10

    Assuming your RoutedCommands are defined statically:

    #region DeleteSelection
    
        /// <summary>
        /// The DeleteSelection command ....
        /// </summary>
        public static RoutedUICommand DeleteSelection
            = new RoutedUICommand("Delete selection", "DeleteSelection", typeof(ChemCommands));
    
        #endregion
    

    Bind in XAML thus:

    <Canvas.InputBindings>
        <KeyBinding Key="Delete" Command="{x:Static Controls:ChemCommands.DeleteSelection}" />
    </Canvas.InputBindings>
    

    Regards,

    Tim Haughton

    0 讨论(0)
  • 2020-12-03 14:11

    I create a Key binding in my view model that links the command and the Key like so

            this.KeyBinding = new KeyBinding();
            //set the properties
            this.KeyBinding.Command = this.Command;
            this.KeyBinding.Key = this.Key;
            //modifier keys may or may not be set
            this.KeyBinding.Modifiers = this.ModifierKeys;
    

    then i create a collection of InputBinding items in my View Model root and add them to the windows InputBindings in my window's code behind

         foreach (var item in applicationViewModel.InputBindingCollection) {
            this.InputBindings.Add(item);
         }
    

    its bad form to do stuff in the code behind i know, but i dont know how to do the binding yet, however im still working on it. :) The only thing this doent give me is a key command modifer list in the menu, but that is to come.

    0 讨论(0)
提交回复
热议问题