• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 105
  • Last Modified:

WPF where are key bindings stored?

In a WPF application, say I have a window, and I set up a key binding to run a command if I press a certain key on the keyboard.

Somewhere in my Window object I expect my key binding is stored. I expect when a key is pressed on the keyboard, that generates a "key was pressed" event, and the operating system determines which window has focus, (and perhaps what control on the window has focus,) and sends the "key was pressed" event to to window, and the window has a list of events it handles, and if there's a match then it calls the corresponding event handler.

But I can't find that list.

Maybe it doesn't work that way. Maybe the window registers the events it's interested in with some higher power, and that higher power keeps the list of events the window handles.

Either way, my problem is I press the key, and... nothing happens.

So I'm trying to trace what happens to this key event, because it's not resulting in my command being called.

Also, is there a list of keyboard key names that can be used in WPF XAML files? I've seen the list of Key Enumerations at https://msdn.microsoft.com/en-us/library/system.windows.input.key(v=vs.110).aspx. It lists "OemPlus" for the keyboard "+" key; however, I've seen XAML code that uses
key="Plus"

Open in new window

, which seems to work, but I don't see that documented anywhere.

So my questions are:

1. Is there documentation for what key names can be used in a WPF XAML file for the "Key="<string>"

2. Is there a way to trace what happens to a keyboard key pressed event when what I'm expecting to happen doesn't happen?
0
deleyd
Asked:
deleyd
1 Solution
 
deleydAuthor Commented:
I found the answer I was looking for. It's in the source code for System.Windows.Input.KeyConverter.cs There the code is:
        private object GetKey(string keyToken, CultureInfo culture)
        { 
            if (keyToken == String.Empty)
            {
                return Key.None;
            } 
            else
            { 
                keyToken = keyToken.ToUpper(culture); 
                if (keyToken.Length == 1 && Char.IsLetterOrDigit(keyToken[0]))
                { 
                    if (Char.IsDigit(keyToken[0]) && (keyToken[0] >= '0' && keyToken[0] <= '9'))
                    {
                        return ((int)(Key)(Key.D0 + keyToken[0] - '0'));
                    } 
                    else if (Char.IsLetter(keyToken[0]) && (keyToken[0] >= 'A' && keyToken[0] <= 'Z'))
                    { 
                        return ((int)(Key)(Key.A + keyToken[0] - 'A')); 
                    }
                    else
                    {
                        throw new ArgumentException(SR.Get(SRID.CannotConvertStringToType, keyToken, typeof(Key)));
                    }
                } 
                else
                { 
                    Key keyFound = (Key)(-1); 
                    switch (keyToken)
                    { 
                        case "ENTER": keyFound = Key.Return; break;
                        case "ESC": keyFound = Key.Escape; break;
                        case "PGUP": keyFound = Key.PageUp; break;
                        case "PGDN": keyFound = Key.PageDown; break; 
                        case "PRTSC": keyFound = Key.PrintScreen; break;
                        case "INS": keyFound = Key.Insert; break; 
                        case "DEL": keyFound = Key.Delete; break; 
                        case "WINDOWS": keyFound = Key.LWin; break;
                        case "WIN": keyFound = Key.LWin; break; 
                        case "LEFTWINDOWS": keyFound = Key.LWin; break;
                        case "RIGHTWINDOWS": keyFound = Key.RWin; break;
                        case "APPS": keyFound = Key.Apps; break;
                        case "APPLICATION": keyFound = Key.Apps; break; 
                        case "BREAK": keyFound = Key.Cancel; break;
                        case "BACKSPACE": keyFound = Key.Back; break; 
                        case "BKSP": keyFound = Key.Back; break; 
                        case "BS": keyFound = Key.Back; break;
                        case "SHIFT": keyFound = Key.LeftShift; break; 
                        case "LEFTSHIFT": keyFound = Key.LeftShift; break;
                        case "RIGHTSHIFT": keyFound = Key.RightShift; break;
                        case "CONTROL": keyFound = Key.LeftCtrl; break;
                        case "CTRL": keyFound = Key.LeftCtrl; break; 
                        case "LEFTCTRL": keyFound = Key.LeftCtrl; break;
                        case "RIGHTCTRL": keyFound = Key.RightCtrl; break; 
                        case "ALT": keyFound = Key.LeftAlt; break; 
                        case "LEFTALT": keyFound = Key.LeftAlt; break;
                        case "RIGHTALT": keyFound = Key.RightAlt; break; 
                        case "SEMICOLON": keyFound = Key.OemSemicolon; break;
                        case "PLUS": keyFound = Key.OemPlus; break;
                        case "COMMA": keyFound = Key.OemComma; break;
                        case "MINUS": keyFound = Key.OemMinus; break; 
                        case "PERIOD": keyFound = Key.OemPeriod; break;
                        case "QUESTION": keyFound = Key.OemQuestion; break; 
                        case "TILDE": keyFound = Key.OemTilde; break; 
                        case "OPENBRACKETS": keyFound = Key.OemOpenBrackets; break;
                        case "PIPE": keyFound = Key.OemPipe; break; 
                        case "CLOSEBRACKETS": keyFound = Key.OemCloseBrackets; break;
                        case "QUOTES": keyFound = Key.OemQuotes; break;
                        case "BACKSLASH": keyFound = Key.OemBackslash; break;
                        case "FINISH": keyFound = Key.OemFinish; break; 
                        case "ATTN": keyFound = Key.Attn; break;
                        case "CRSEL": keyFound = Key.CrSel; break; 
                        case "EXSEL": keyFound = Key.ExSel; break; 
                        case "ERASEEOF": keyFound = Key.EraseEof; break;
                        case "PLAY": keyFound = Key.Play; break; 
                        case "ZOOM": keyFound = Key.Zoom; break;
                        case "PA1": keyFound = Key.Pa1; break;
                        default: keyFound = (Key)Enum.Parse(typeof(Key), keyToken, true); break;
                    } 
 
                    if ((int)keyFound != -1) 
                    { 
                        return keyFound;
                    } 
                    return null;
                }
            }
        } 

Open in new window

There's where "Plus" gets converted to Key.OemPlus. And if the string case statement doesn't match anything, then Enum.Parse is used to convert "OemPlus" to Key.OemPlus.

And I finally did find the list of key bindings, though it's buried deep:
Key Binding for OemMinus key (part 1)Key Binding for OemMinus key (part 2)
(I'm still not sure if there's a way to debug what happens to a keyboard key event if nothing happens and I'm expecting something to happen. The event might be handled somewhere else before it gets to where I expect it to go.)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now