WPF Button key down modifies click command in XAML/MVVM

In WPF I can easily create command and command handler in ViewModel and easily connect it to Button control in XAML (View) by following standard MVVM design pattern . I can also define InputBindings and CommandBindings in XAML (View) to handle key down and then execute command in ViewModel. Currently have one command on button and it is executed when button is clicked. But how can I, at the same time, handle click on the button and if key modifier is pressed, and then execute another command? Key modifier would be Left or Right Alt.


You could implement an attached behaviour:

namespace WpfApplication1
{
    public class CombinedMouseAndKeyCommandBehavior
    {
        public static readonly DependencyProperty KeyProperty = DependencyProperty.RegisterAttached("Key", typeof(Key),
           typeof(CombinedMouseAndKeyCommandBehavior), new PropertyMetadata(Key.None, new PropertyChangedCallback(OnKeySet)));

        public static Key GetKey(FrameworkElement element) => (Key)element.GetValue(KeyProperty);

        public static void SetKey(FrameworkElement element, Key value) => element.SetValue(KeyProperty, value);

        public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("Command", typeof(ICommand),
            typeof(CombinedMouseAndKeyCommandBehavior), new PropertyMetadata(null));

        public static ICommand GetCommand(FrameworkElement element) => (ICommand)element.GetValue(CommandProperty);

        public static void SetCommand(FrameworkElement element, ICommand value) => element.SetValue(CommandProperty, value);

        private static void OnKeySet(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement fe = d as FrameworkElement;
            fe.PreviewMouseLeftButtonDown += Fe_PreviewMouseLeftButtonDown;
        }

        private static void Fe_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            FrameworkElement fe = sender as FrameworkElement;
            Key key = GetKey(fe);
            ICommand command = GetCommand(fe);
            if(key != Key.None && command != null && Keyboard.IsKeyDown(key))
            {
                command.Execute(null);
            }
        }
    }
}

Usage:

<Button Content="Test command"
                xmlns:local="clr-namespace:WpfApplication1"
                local:CombinedMouseAndKeyCommandBehavior.Command="{Binding RemoveCommand}"
                local:CombinedMouseAndKeyCommandBehavior.Key="F">
    <Button.InputBindings>
        <MouseBinding Gesture="LeftClick" Command="{Binding AddCommand }" />
    </Button.InputBindings>
</Button>

Introduction to Attached Behaviors in WPF: https://www.codeproject.com/Articles/28959/Introduction-to-Attached-Behaviors-in-WPF


You may read pressed key only from focused WPF element. In your case you are able to get it from window(page).

XAML

<Window x:Class="Application.MainWindow"
    mc:Ignorable="d"
    Title="MainWindow"
    KeyDown="MainWindow_OnKeyDown"
    x:Name="RootKey">

Code-behind

private void MainWindow_OnKeyDown(object sender, KeyEventArgs e)
{
    var dataContext = (MainPageViewModel) this.DataContext;
    dataContext.KeyModifer = e.SystemKey.ToString();
}

ViewModel

internal class MainPageViewModel : ViewModelBase
{
    public string KeyModifer { private get; set;}
    ...
}

通过在下面的输入绑定示例上设置修饰符属性,在XAML中执行此操作。

<TextBox.InputBindings>
    <KeyBinding Key="Enter" Command="{Binding SaveCommand}" Modifiers="Alt"/>
    <KeyBinding Key="Enter" Command="{Binding AnotherSaveCommand}"/>
</TextBox.InputBindings>
链接地址: http://www.djcxy.com/p/56142.html

上一篇: 通过mvvm无法访问嵌套wpf项目命令

下一篇: 按下WPF按键,修改XAML / MVVM中的点击命令