如何检测在 OEM 键 C# 中何时按下(向前)斜杠键

How to detect when (forward) slash key is pressed in OEM keys C#

我正在开发 wpf c# 应用程序,我需要检测用户何时按下“/”,但我无法找到“/ " e.Key,我看到有 Key.OemBackslash 之类的东西,但我找不到 " / "(正斜杠)的正确事件 ...

谢谢大家, 干杯

您可以通过以下方法(see this site)从键中获取字符。

protected override void OnPreviewKeyDown(KeyEventArgs e)
{
        bool toUnicodeIsTrue=false;
        char t = GetCharFromKey(e.Key, ref toUnicodeIsTrue);
        if ( t == '/')
        {
            // do stuff
        }
        base.OnPreviewKeyDown(e);  
}


    public static char GetCharFromKey(System.Windows.Input.Key key, ref bool toUnicodeIsTrue)
    {
        toUnicodeIsTrue = true;
        char ch = ' ';

        // First, you need to get the VirtualKey code. Thankfully, there’s a simple class 
        // called KeyInterop, which exposes a static method VirtualKeyFromKey 
        // that gets us this information
        int virtualKey = System.Windows.Input.KeyInterop.VirtualKeyFromKey(key);
        //Then, we need to get the character. This is much trickier. 
        //First we have to get the keyboard state and then we have to map that VirtualKey 
        //we got in the first step to a ScanCode, and finally, convert all of that to Unicode, 
        //because .Net doesn’t really speak ASCII
        byte[] keyboardState = new byte[256];
        GetKeyboardState(keyboardState);

        uint scanCode = MapVirtualKey((uint)virtualKey, MapType.MAPVK_VK_TO_VSC);
        StringBuilder stringBuilder = new StringBuilder(2);

        int result = ToUnicode((uint)virtualKey, scanCode, keyboardState, stringBuilder, stringBuilder.Capacity, 0);
        switch (result)
        {
            case -1:
                toUnicodeIsTrue = false;
                break;
            case 0:
                toUnicodeIsTrue = false;
                break;
            case 1:
                {
                    ch = stringBuilder[0];
                    break;
                }
            default:
                {
                    ch = stringBuilder[0];
                    break;
                }
        }
        return ch;
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool GetKeyboardState(byte[] lpKeyState);
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern uint MapVirtualKey(uint uCode, MapType uMapType);
    public enum MapType : uint
    {
        MAPVK_VK_TO_VSC = 0x0,
        MAPVK_VSC_TO_VK = 0x1,
        MAPVK_VK_TO_CHAR = 0x2,
        MAPVK_VSC_TO_VK_EX = 0x3,
    }
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern int ToUnicode(
        uint wVirtKey,
        uint wScanCode,
        byte[] lpKeyState,
        [System.Runtime.InteropServices.Out, System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr, SizeParamIndex = 4)]
        StringBuilder pwszBuff,
        int cchBuff,
        uint wFlags);
}

我的旧答案:

protected override void OnPreviewKeyDown(KeyEventArgs e)
{ //***
    if (e.Key == Key.Oem2)
    {  
        // do stuff
    }
    base.OnPreviewKeyDown(e);
}

请注意,名称以 "oem"(原始设备制造商)开头,这意味着键盘制造商对其功能负责,并且它因本地键盘而异。所以,你可以在

中设置一个断点
{//*** 

我的代码行并检查 e.Key 属性。

在美式键盘上应该是 Key.OemQuestion。但是在瑞典语键盘上它是 D7 所以这取决于。键盘上的按键并不总是产生相同的字符。

根据您要执行的操作,处理 PreviewTextInput 事件可能会更好:

protected override void OnPreviewTextInput(TextCompositionEventArgs e)
{
    base.OnPreviewTextInput(e);
    if (e.Text == "/")
    {
        Debug.WriteLine("...");
    }
}