Wpf 组合键事件

Wpf 组合键事件,wpf,mvvm,Wpf,Mvvm,根据要求,我需要捕获两个字符和一个控制键组合的事件(例如(ALT+S+C)。 如何实现相同的功能 谢谢 Ranish使用向下键事件: if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) // Is Alt key pressed { if (Keyboard.IsKeyDown(Key.S) && Keyboard.IsKeyDown(Key.C)) { // d

根据要求,我需要捕获两个字符和一个控制键组合的事件(例如(ALT+S+C)。 如何实现相同的功能

谢谢
Ranish

使用
向下键
事件:

if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) // Is Alt key pressed
{
    if (Keyboard.IsKeyDown(Key.S) && Keyboard.IsKeyDown(Key.C))
    {
        // do something here
    }
}

如果你想把一个动作绑定到这个组合上

<KeyBinding Gesture="Alt+S+C" Command="{Binding YourCommand}" />


参见此

您可以使用以下代码进行检测

    private void UIElement_OnPreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (Keyboard.Modifiers == ModifierKeys.Alt && Keyboard.IsKeyDown(Key.S)
            && Keyboard.IsKeyDown(Key.C))
        {
            //if you want, you can fire event here
        }
    }

编辑:修改的代码。不能同时使用
手势
属性。最后声明的属性将用作键,而
手势
属性中指定的键将被忽略

以下代码仅适用于2个ModifierKeys,而不是2个键:

<KeyBinding Gesture="Alt+Shift+C" Command="{Binding ACommand}"/>

要使用两个键和一个
ModifierKey
实现组合键,下面的文章看起来非常有用:


如果目的是允许用户通过控件输入字符序列 在VisualStudio中使用注释/取消注释宏之类的键,然后您可以执行类似的操作(这非常粗糙,只是为了让您了解它的工作原理)

添加一个自定义控件,该控件在其窗口上查找按键,并保存一组要监视的手势

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;

namespace WpfApplication4
{
    [ContentProperty("Gestures")]
    public class KeyGestures : Control
    {
        public List<IKeyGesture> Gestures
        {
            get { return (List<IKeyGesture>)GetValue(GesturesProperty); }
            set { SetValue(GesturesProperty, value); }
        }
        public static readonly DependencyProperty GesturesProperty =
            DependencyProperty.Register("Gestures", typeof(List<IKeyGesture>), typeof(KeyGestures), new PropertyMetadata(null));

        public List<string> CurrentSequence
        {
            get { return (List<string>)GetValue(CurrentSequenceProperty); }
            set { SetValue(CurrentSequenceProperty, value); }
        }
        public static readonly DependencyProperty CurrentSequenceProperty =
            DependencyProperty.Register("CurrentSequence", typeof(List<string>), typeof(KeyGestures), new PropertyMetadata(null));

        public KeyGestures()
        {
            Gestures = new List<IKeyGesture>();
            CurrentSequence = new List<string>();
        }

        protected override void OnInitialized(EventArgs e)
        {
            var hostWindow = Window.GetWindow(this);
            if (hostWindow != null)
            {
                hostWindow.PreviewKeyDown += hostWinow_PreviewKeyDown;
                hostWindow.PreviewKeyUp += hostWinow_PreviewKeyUp;
            }
            base.OnInitialized(e);
        }

        bool IsAnyKeyPressed()
        {
            var allPossibleKeys = Enum.GetValues(typeof(Key));
            bool results = false;
            foreach (var currentKey in allPossibleKeys)
            {
                Key key = (Key)currentKey;
                if (key != Key.None)
                    if (Keyboard.IsKeyDown((Key)currentKey)) { results = true; break; }
            }
            return results;
        }

        void hostWinow_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (!IsAnyKeyPressed())
            {
                CurrentSequence.Clear();
            }
        }

        void hostWinow_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.SystemKey == Key.None)
            {
                if (!CurrentSequence.Contains(e.Key.ToString()))
                    CurrentSequence.Add(e.Key.ToString());
            }
            else
                if (!CurrentSequence.Contains(e.SystemKey.ToString()))
                    CurrentSequence.Add(e.SystemKey.ToString());

            foreach (var gesture in Gestures)
                if (gesture.IsComplete(this.CurrentSequence))
                {
                    if (gesture.Command != null && gesture.Command.CanExecute(gesture.CommandParameter))
                        gesture.Command.Execute(gesture.CommandParameter);
                    System.Diagnostics.Debug.WriteLine("Completed gesture " + gesture);
                }
        }

    }

    public interface IKeyGesture
    {
        bool IsComplete(List<string> currentSequence);
        ICommand Command { get; }
        object CommandParameter { get; set; }
    }

    public class SequenceKeyGesture : DependencyObject, IKeyGesture
    {
        public string Sequence { get; set; }
        public char SplitChar { get; set; }
        public ICommand Command { get; set; }


        public object CommandParameter
        {
            get { return (object)GetValue(CommandParameterProperty); }
            set { SetValue(CommandParameterProperty, value); }
        }
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register("CommandParameter", typeof(object), typeof(SequenceKeyGesture), new PropertyMetadata(null));


        public bool IsComplete(List<string> currentSequence)
        {

            string[] splitSequence = Sequence.Split(SplitChar);
            if (splitSequence.Length != currentSequence.Count) return false;
            if (splitSequence != null && splitSequence.Length > 0)
                for (int i = 0; i < splitSequence.Length; i++)
                    if (splitSequence[i] != currentSequence[i])
                        return false;

            return true;
        }
        public SequenceKeyGesture()
        {
            SplitChar = '+';
        }
        public override string ToString()
        {
            return Sequence;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
使用System.Windows.Markup;
命名空间WpfApplication4
{
[内容属性(“手势”)]
公共类键手势:控件
{
公开列表手势
{
获取{return(List)GetValue(GesturesProperty);}
set{SetValue(GesturesProperty,value);}
}
公共静态只读依赖项Property GesturesProperty=
DependencyProperty.Register(“手势”、typeof(列表)、typeof(按键手势)、new PropertyMetadata(null));
公共列表序列
{
获取{return(List)GetValue(CurrentSequenceProperty);}
set{SetValue(CurrentSequenceProperty,value);}
}
公共静态只读DependencyProperty CurrentSequenceProperty=
DependencyProperty.Register(“CurrentSequence”、typeof(List)、typeof(KeyPictures)、new PropertyMetadata(null));
公钥手势()
{
手势=新列表();
CurrentSequence=新列表();
}
已初始化受保护的覆盖无效(事件参数e)
{
var hostWindow=Window.GetWindow(这个);
如果(主机窗口!=null)
{
hostWindow.PreviewKeyDown+=hostWinow\u PreviewKeyDown;
hostWindow.PreviewKeyUp+=hostWinow\u PreviewKeyUp;
}
基础。初始化(e);
}
bool IsAnyKeyPressed()
{
var allPossibleKeys=Enum.GetValues(typeof(Key));
bool结果=假;
foreach(所有可能的键中的var currentKey)
{
Key Key=(Key)currentKey;
if(key!=key.None)
if(Keyboard.IsKeyDown((Key)currentKey)){results=true;break;}
}
返回结果;
}
void hostWinow_PreviewKeyUp(对象发送方,System.Windows.Input.KeyEventArgs e)
{
如果(!IsAnyKeyPressed())
{
CurrentSequence.Clear();
}
}
void hostWinow_PreviewKeyDown(对象发送方,System.Windows.Input.KeyEventArgs e)
{
如果(e.SystemKey==Key.None)
{
如果(!CurrentSequence.Contains(例如Key.ToString()))
CurrentSequence.Add(例如Key.ToString());
}
其他的
如果(!CurrentSequence.Contains(例如SystemKey.ToString()))
CurrentSequence.Add(例如SystemKey.ToString());
foreach(手势中的var手势)
if(手势.IsComplete(此.CurrentSequence))
{
if(sipple.Command!=null&&sipple.Command.CanExecute(sipple.CommandParameter))
手势.命令.执行(手势.命令参数);
System.Diagnostics.Debug.WriteLine(“完成的手势”+手势);
}
}
}
公共界面手势
{
bool IsComplete(列表当前顺序);
ICommand命令{get;}
对象命令参数{get;set;}
}
公共类SequenceKeyPirset:DependencyObject,ikeyPirset
{
公共字符串序列{get;set;}
公共字符SplitChar{get;set;}
公共ICommand命令{get;set;}
公共对象命令参数
{
获取{return(object)GetValue(CommandParameterProperty);}
set{SetValue(CommandParameterProperty,value);}
}
public static readonly dependencProperty命令参数解释属性=
Register(“CommandParameter”、typeof(object)、typeof(sequencekeypership)、newpropertyMetadata(null));
公共布尔值已完成(列表当前顺序)
{
string[]splitSequence=Sequence.Split(SplitChar);
如果(splitSequence.Length!=currentSequence.Count)返回false;
if(splitSequence!=null&&splitSequence.Length>0)
for(int i=0;i
然后可以将其与以下xaml一起使用

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication4"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <local:KeyGestures>
            <local:SequenceKeyGesture Sequence="LeftAlt~S~C" SplitChar="~" Command="{Command binding here}" CommandParameter="Action1" />
            <local:SequenceKeyGesture Sequence="LeftAlt+S+V" Command="{Command binding here" CommandParameter="Action2"/>
        </local:KeyGestures>
    </Grid>
</Window>

在那里有一个Debug.WriteLine,当手势被触发时向您显示,以防
 <interactivity:EventTrigger EventName="KeyDown">
            <mvvmlight:EventToCommand Command="{Binding Command}" PassEventArgsToCommand="True" />
        </interactivity:EventTrigger>




 private void Event()
 {

    if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
    {  
                    if (Keyboard.IsKeyDown(Key.C) && Keyboard.IsKeyDown(Key.T))
                    {
                     //code
                    }
    }
 }