Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF按钮向下键修改XAML/MVVM中的单击命令_Wpf_Mvvm_Click_Command_Key Bindings - Fatal编程技术网

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

WPF按钮向下键修改XAML/MVVM中的单击命令,wpf,mvvm,click,command,key-bindings,Wpf,Mvvm,Click,Command,Key Bindings,在WPF中,我可以在ViewModel中轻松创建命令和命令处理程序,并通过遵循标准MVVM设计模式,轻松地将其连接到XAML(视图)中的按钮控件。我还可以在XAML(视图)中定义InputBindings和CommandBindings来处理键关闭,然后在ViewModel中执行命令。 当前在按钮上有一个命令,单击按钮时执行该命令。 但我如何才能同时处理点击按钮,如果按下键修改器,然后执行另一个命令?按键修改器可以是左键或右键。您只能从聚焦的WPF元素中读取按下的按键。在您的情况下,您可以从窗口

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

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

XAML

视图模型

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

通过在下面的输入绑定示例上设置modifiers属性,在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中附加行为介绍:

谢谢,这也是我的结论。甚至在窗口上添加了KeyUp处理程序来重置ViewModel中的属性。。。然而,这打破了MVVM模式,因为视图直接更改代码隐藏文件中的属性。由于这应该放在主应用程序窗口中,现在这个窗口非常复杂,所以它不会像我希望的那样通过遵循MVVM模式来维护和优雅。。。但是,如果无法以任何其他方式解决此问题,我将不得不保持原样…当我们使用两个键(而不是鼠标)时,这将很好。如何通过鼠标单击+向下键来执行另一个命令来实现相同的效果?曾尝试:
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>