How to detect multiple keys down onkeydown event in wpf?

前端 未结 3 964
走了就别回头了
走了就别回头了 2020-12-03 23:28

I don\'t want to detect any double key combination, so solutions like

if(Keyboard.IsKeyDown(specificKey)){

}

won\'t work, unless of cours

相关标签:
3条回答
  • 2020-12-03 23:34

    This is a tested and working solution with several improvements. I use it to make a textbox that reads input combos to use later on as Hotkeys.

    Features: AllowedKeys, MaxKeyCount and ModifierKeys check. Each of them can be removed if not needed.

    XAML:

    <Window x:Class="KeyTestApp.KeyTestWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="KeyTestWindow" SizeToContent="WidthAndHeight">
        <StackPanel>
            <TextBox PreviewKeyDown="TextBox_KeyDown" Height="20" Width="165" Name="tbHotkeys" />
        </StackPanel>
    </Window>
    

    CodeBehind:

    /// <summary>
    /// Interaction logic for KeyTestWindow.xaml
    /// </summary>
    public partial class KeyTestWindow : Window
    {
        int MaxKeyCount = 3;
        List<Key> PressedKeys = new List<Key>();
        List<Key> AllowedKeys = new List<Key>();
    
        public KeyTestWindow()
        {
            InitializeComponent();
            tbHotkeys.Focus();
    
            //Init the allowed keys list
            AllowedKeys.Add(Key.LeftCtrl);
            AllowedKeys.Add(Key.A);
            AllowedKeys.Add(Key.B);
            AllowedKeys.Add(Key.LeftShift);
        }
    
        private void TextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Handled) return;
    
            //Check all previous keys to see if they are still pressed
            List<Key> KeysToRemove = new List<Key>();
            foreach (Key k in PressedKeys)
            {
                if (!Keyboard.IsKeyDown(k))
                    KeysToRemove.Add(k);
            }
    
            //Remove all not pressed keys
            foreach (Key k in KeysToRemove)
                PressedKeys.Remove(k);
    
            //Add the key if max count is not reached
            if (PressedKeys.Count < MaxKeyCount)
                //Add the key if it is part of the allowed keys
                //if (AllowedKeys.Contains(e.Key))
                if (!PressedKeys.Contains(e.Key))
                    PressedKeys.Add(e.Key);
    
            PrintKeys();
    
            e.Handled = true;
        }
    
        private void PrintKeys()
        {
            //Print all pressed keys
            string s = "";
            if (PressedKeys.Count == 0) return;
    
            foreach (Key k in PressedKeys)
                if (IsModifierKey(k))
                    s += GetModifierKey(k) + " + ";
                else
                    s += k + " + ";
    
            s = s.Substring(0, s.Length - 3);
            tbHotkeys.Text = s;
        }
    
        private bool IsModifierKey(Key k)
        {
            if (k == Key.LeftCtrl || k == Key.RightCtrl ||
                k == Key.LeftShift || k == Key.RightShift ||
                k == Key.LeftAlt || k == Key.RightAlt ||
                k == Key.LWin || k == Key.RWin)
                return true;
            else
                return false;
        }
    
        private ModifierKeys GetModifierKey(Key k)
        {
            if (k == Key.LeftCtrl || k == Key.RightCtrl)
                return ModifierKeys.Control;
    
            if (k == Key.LeftShift || k == Key.RightShift)
                return ModifierKeys.Shift;
    
            if (k == Key.LeftAlt || k == Key.RightAlt)
                return ModifierKeys.Alt;
    
            if (k == Key.LWin || k == Key.RWin)
                return ModifierKeys.Windows;
    
            return ModifierKeys.None;
        }
    }
    
    0 讨论(0)
  • 2020-12-03 23:35

    Refactored your code: XAML: <TextBox Text="text" LostFocus="TextBox_LostFocus" KeyDown="TextBox_KeyDown" KeyUp="TextBox_KeyUp"/>

    code-behind:

    List<Key> _pressedKeys = new List<Key>();
    
    
    private void TextBox_KeyDown(object sender, KeyEventArgs e)
    {
        if (_pressedKeys.Contains(e.Key))
            return;
        _pressedKeys.Add(e.Key);
    
    
        PrintKeys();
        e.Handled = true;
    }
    
    private void TextBox_KeyUp(object sender, KeyEventArgs e)
    {
        _pressedKeys.Remove(e.Key);
        PrintKeys();
        e.Handled = true;
    
    }
    
    private void PrintKeys()
    {
        StringBuilder b = new StringBuilder();
    
        b.Append("Combination: ");
        foreach (Key key in _pressedKeys)
        {
            b.Append(key.ToString());
            b.Append("+");
        }
        b.Length--;
        Console.WriteLine(b.ToString());
    }
    
    private void TextBox_LostFocus(object sender, RoutedEventArgs e)
    {
        _pressedKeys.Clear();
    }
    
    0 讨论(0)
  • 2020-12-03 23:35

    You should use key modifier in combination with your customized key

    if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) // Is Alt key pressed
    {
      if (Keyboard.IsKeyDown(Key.S) && Keyboard.IsKeyDown(Key.C))
      {
        // do something here
      }
     }
    
    0 讨论(0)
提交回复
热议问题