检测是否在C#中按下任何键(不是A,B,但是任何键)

Chr*_*ert 10 c# keyboard wpf key input

[编辑3]我使用"奇怪"版本"解决了它".至少对于最重要的键.这对我的情况来说是足够的,我想检查ALT和ALT + A是不一样的(从而确保没有按下A).不完美,但已经有很多时间来解决这么小的问题了.无论如何,感谢所有的答案... [编辑3]

[编辑4]由于280Z28 [/ EDIT 4]解决了它更清洁

我知道如何检查修改键以及如何测试单个键.问题是,我想检查是否按下了任何键.以下方法似乎"奇怪":-)

用C#编写的WPF应用程序

if (Keyboard.IsKeyDown(Key.A)) return true;
if (Keyboard.IsKeyDown(Key.B)) return true;
if (Keyboard.IsKeyDown(Key.C)) return true;
Run Code Online (Sandbox Code Playgroud)

我知道这是一个枚举,所以我想到了一个循环,但是使用的"最大数字"是什么.这可能吗?顺便说一句,这是一个非常特殊的情况,通常我会使用一个事件,但在这种情况下我必须这样做.不幸的是,没有"list"Keyboard.CurrentlyDownKeys.至少我没看到它.

谢谢,克里斯

编辑:好的,因为它似乎是一个更大的交易,这里的原因是:我已经定义了一个"KeySet",它作为自定义函数的DictionaryKey.如果有人点击某个元素,则包装器会遍历字典并检查是否有任何预定义的"Keysets"处于活动状态.

这允许我定义简单的触发器,例如,如果按下ALT + A + B,则运行此功能.另一个选项是例如,如果按下ALT + STRG + A(在鼠标单击WPF元素期间),则运行此功能.

当前实现的唯一"问题",如果我定义一个不包含任何REAL键的Keyset,如按下ALT则运行,如果按下ALT + A,也会触发它.哦,在写这篇文章时,我意识到还有另外一个问题.如果按下ALT + A + B + C,ALT + A + B当前也会触发.

也许我的方法是错误的,我应该创建一个"静态密钥跟踪器"并将密钥集与其值进行比较(通过事件获取)..我将尝试一下.

编辑2 这不起作用,至少不是一个简单的方法.我需要一个FrameworkElement来附加到KeyDown,但我没有在静态构造函数中.我对某个元素的KeyDownEvents不感兴趣,但是"全局"...我认为我推迟了这个问题,它并不那么重要.不过,如果有人知道更好的不同方法......

很长一段时间,对于任何关心的人,这里有一些代码:

    public class KeyModifierSet
{
    internal readonly HashSet<Key> Keys = new HashSet<Key>();
    internal readonly HashSet<ModifierKeys> MKeys = new HashSet<ModifierKeys>();

    public override int GetHashCode()
    {
        int hash = Keys.Count + MKeys.Count;
        foreach (var t in Keys)
        {
            hash *= 17;
            hash = hash + t.GetHashCode();
        }
        foreach (var t in MKeys)
        {
            hash *= 19;
            hash = hash + t.GetHashCode();
        }
        return hash;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as KeyModifierSet);
    }
    public bool Equals(KeyModifierSet other)
    {
        // Check for null
        if (ReferenceEquals(other, null))
            return false;

        // Check for same reference
        if (ReferenceEquals(this, other))
            return true;

        // Check for same Id and same Values
        return Keys.SetEquals(other.Keys) && MKeys.SetEquals(other.MKeys);
    }

    public bool IsActive()
    {
        foreach (var k in Keys)
            if (Keyboard.IsKeyUp(k)) return false;

        if ((Keys.Count == 0) && !Keyboard.IsKeyDown(Key.None)) return false;


        foreach (var k in MKeys)
            if ((Keyboard.Modifiers & k) == 0) return false;

        if ((MKeys.Count == 0) && Keyboard.Modifiers > 0) return false;

        return true;
    }


    public KeyModifierSet(ModifierKeys mKey)
    {
        MKeys.Add(mKey);
    }
    public KeyModifierSet()
    {

    }
    public KeyModifierSet(Key key)
    {
        Keys.Add(key);
    }
    public KeyModifierSet(Key key, ModifierKeys mKey)
    {
        Keys.Add(key);
        MKeys.Add(mKey);
    }
    public KeyModifierSet Add(Key key)
    {
        Keys.Add(key);
        return this;
    }
    public KeyModifierSet Add(ModifierKeys key)
    {
        MKeys.Add(key);
        return this;
    }
}
Run Code Online (Sandbox Code Playgroud)

Sam*_*ell 11

[DllImport("user32.dll", EntryPoint = "GetKeyboardState", SetLastError = true)]
private static extern bool NativeGetKeyboardState([Out] byte[] keyStates);

private static bool GetKeyboardState(byte[] keyStates)
{
    if (keyStates == null)
        throw new ArgumentNullException("keyState");
    if (keyStates.Length != 256)
        throw new ArgumentException("The buffer must be 256 bytes long.", "keyState");
    return NativeGetKeyboardState(keyStates);
}

private static byte[] GetKeyboardState()
{
    byte[] keyStates = new byte[256];
    if (!GetKeyboardState(keyStates))
        throw new Win32Exception(Marshal.GetLastWin32Error());
    return keyStates;
}

private static bool AnyKeyPressed()
{
    byte[] keyState = GetKeyboardState();
    // skip the mouse buttons
    return keyState.Skip(8).Any(state => (state & 0x80) != 0);
}
Run Code Online (Sandbox Code Playgroud)


小智 5

使用 XNA 框架,您可以使用 thw follow 来检查是否按下了任何键。

Keyboard.GetState().GetPressedKeys().Length > 0
Run Code Online (Sandbox Code Playgroud)

  • 也许是因为 OP 试图做的事情通常只在电子游戏中完成...... (3认同)

And*_*ndy 5

这是一个相当老的问题,但如果有人遇到这个问题并且不想使用外部 dll,您可以枚举可能的键并循环它们。

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;
}
Run Code Online (Sandbox Code Playgroud)

您可以通过在函数外部执行枚举并保留列表以供以后使用来对此进行优化。