wpf 如何检测wpf中的多个按键按下onkeydown事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19013087/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:43:49  来源:igfitidea点击:

How to detect multiple keys down onkeydown event in wpf?

c#wpfevents

提问by CoolCodeBro

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

我不想检测任何双键组合,所以解决方案像

if(Keyboard.IsKeyDown(specificKey)){

}

won't work, unless of course, I will have check every single key state, which I'm hoping I won't have to do. .

不会工作,当然,除非我会检查每个关键状态,我希望我不必这样做。.

    private void TextBox_KeyDown_1(object sender, KeyEventArgs e)
    {
      Console.WriteLine(combination of keys pressed);
    }

EDIT: The end goal is to detect ANY (not a specific combination/single key) key combination.

编辑:最终目标是检测任何(不是特定的组合/单键)组合键。

EDIT2: LadderLogic's solution works perfectly.

EDIT2:LadderLogic 的解决方案完美运行。

采纳答案by LadderLogic

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

重构您的代码: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();
}

回答by BRAHIM Kamel

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

回答by mandarin

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, MaxKeyCountand ModifierKeyscheck. Each of them can be removed if not needed.

特点:AllowedKeysMaxKeyCountModifierKeys检查。如果不需要,它们中的每一个都可以删除。

XAML:

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