How to detect when (forward) slash key is pressed

2020-02-12 07:50发布

I'm working on wpf c# application and I need to detect when user press "/" but I'm having trouble with finding " / " e.Key, I saw there is Key.OemBackslash and stuffs like that, but I can't find right event for " / " (forward slash) ...

Thanks guys, Cheers

标签: c# wpf key slash
2条回答
何必那么认真
2楼-- · 2020-02-12 07:58

You can the following methods (see this site) to get the character from the key.

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

My old Answer:

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

Note that the name starts with "oem" (Original Equipment Manufacturer), which means the keyboard manufacturer is responsible for its functionality and it varies in local keyboards. So, you can set a break point in

{//*** 

line of my code and check e.Key property.

查看更多
聊天终结者
3楼-- · 2020-02-12 08:01

It should be Key.OemQuestion on a US keyboard. But on a Swedish keyboard it is D7 so it depends. The keys on the keyboard doesn't always produce the same character.

Depending on what you are trying to do you may be better off handling the PreviewTextInput event:

protected override void OnPreviewTextInput(TextCompositionEventArgs e)
{
    base.OnPreviewTextInput(e);
    if (e.Text == "/")
    {
        Debug.WriteLine("...");
    }
}
查看更多
登录 后发表回答