WPF 按钮键按下修改 XAML/MVVM 中的单击命令



在 WPF 中,我可以轻松地在 ViewModel 中创建命令和命令处理程序,并通过遵循标准的 MVVM 设计模式轻松地将其连接到 XAML (View) 中的按钮控件。我还可以在 XAML (View) 中定义 InputBindings 和 CommandBindings 来处理键关闭,然后在 ViewModel 中执行命令。目前有一个按钮上的命令,它在单击按钮时执行。但是,我如何同时处理单击按钮,如果按下键修饰符,然后执行另一个命令?键修饰符将为左或右 Alt。

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

<TextBox.InputBindings>
    <KeyBinding Key="Enter" Command="{Binding SaveCommand}" Modifiers="Alt"/>
    <KeyBinding Key="Enter" Command="{Binding AnotherSaveCommand}"/>
</TextBox.InputBindings>

您可以实现附加行为:

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);
            }
        }
    }
}

用法:

<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>

WPF 中的附加行为简介:https://www.codeproject.com/Articles/28959/Introduction-to-Attached-Behaviors-in-WPF

您只能从焦点 WPF 元素读取按下的键。在您的情况下,您可以从窗口(页面)获取它。

XAML

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

代码隐藏

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

视图模型

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

最新更新