wpf 按键组合事件

j91ykkif  于 2023-05-08  发布在  其他
关注(0)|答案(6)|浏览(248)

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

af7jpaap

af7jpaap1#

使用KeyDown事件:

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

gk7wooem2#

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

下面的代码只能使用2个ModifierKeys,而不是2个Keys:

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

要实现2个键和一个ModifierKey的组合键,下面的文章看起来很有用:
KeyGesture with Multiple Keys

nwlls2ji

nwlls2ji3#

XAML:

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

qlckcl4x4#

如果你想用这个组合来绑定一个动作,

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

看到这个msdn link

irtuqstp

irtuqstp5#

你可以使用下面的代码来检测,

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

nr9pn0ug6#

如果目的是允许用户使用控制键输入一系列字符,就像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;
        }
    }
}

然后,这可以与下面的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来显示手势何时被触发,以防你想在不设置命令的情况下进行测试。

相关问题