/ Published in: C#
I've been trying to figure out a way to make ComboBox items selectable by the keyboard, much like how any ComboBox, ListBox, Selection box is in any other language like HTML, Windows Forms, etc.
Most of the solutions I've seen online weren't particularly useful, or required the use of some third-party DLLs. My solution is a little different, and does not require any new references.
My method works by extending the ComboBox. To use it, all you need to do is call .SetKeyboardSelection() on ComboBox *after* all ComboBoxItems have been added to the ComboBox.
Most of the solutions I've seen online weren't particularly useful, or required the use of some third-party DLLs. My solution is a little different, and does not require any new references.
My method works by extending the ComboBox. To use it, all you need to do is call .SetKeyboardSelection() on ComboBox *after* all ComboBoxItems have been added to the ComboBox.
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
string[] state = new string[] { "Alabama", "Alaska", "Arizona", "Arkansas", "Delaware", "Louisiana", "Maine" }; for (int i = 0; i < state.Length; i++) { comboBoxItem.Content = state[i]; comboBox.Items.Add(comboBoxItem); } //Must enable keyboard selection **AFTER** it all items have bene added to the ComboBox comboBox.SetKeyboardSelection(true); ... public static class Extensions { /* * SetKeyboardSelection enables keyboard selection on all * ComboBoxItems, as well as on the ComboBox itself (it has not already been added). * In addition, it tracks the "search history" that is created as the user types. * This is done to allow the user to type in more letters to narrow down * results (ie. "Ala" = Alabama, Alaska; "Alab" = Alabama) */ public static void SetKeyboardSelection(this ComboBox comboBox, bool enable) { string searchStringEnabled = "KeyboardSelectionEnabled"; string comboBoxTag = comboBox.Tag==null? "" : comboBox.Tag.ToString(); //See if our search history control already exists by analyzing the combobox tag... bool isKeyboardEnabled = comboBoxTag.Contains(searchStringEnabled); /* * KeyPressSearch is defined as an anonymous delegate, that SetKeyboardSelection delegates * to the KeyUp events of ComboBoxItems and the parent ComboBox. */ #region KeyPressSearch KeyEventHandler keyPressSearch = delegate(object sender, KeyEventArgs e) { //Since Key has only certain values, A-Z, D0-D9, NumPad0-9, Space, etc. let's just focus on //letters, and numbers, and ignore all other keys... if they're pressed, clear the search history //another option is to use PlatformKeyCode, but since it's platform specific, let's not. string key = e.Key.ToString(); if (key.Length > 1 && (key.StartsWith("D") || key.StartsWith("NumPad"))) { //remove the D/NumPad prefix to get the digit key = key.Replace("NumPad", "").Replace("D", ""); } else if (key.Length > 1) { comboBox.Tag = searchStringEnabled + "||"; return; } string searchHistoryPartsString = comboBox.Tag == null ? searchStringEnabled + "||" : comboBox.Tag.ToString(); string[] searchHistoryParts = (searchHistoryPartsString.Contains("|")) ? searchHistoryPartsString.Split('|') : new string[0]; int historyExpiration = 1500; //In 1.5 seconds, clear the history, and start new... string searchStringHistory = searchHistoryParts.Length == 3 ? searchHistoryParts[1] : ""; string searchStringTimeStampString = searchHistoryParts.Length == 3 ? searchHistoryParts[2] : ""; DateTime searchStringTimeStamp; string searchString = key; if (DateTime.TryParse(searchStringTimeStampString, out searchStringTimeStamp) && DateTime.Now.Subtract(searchStringTimeStamp).TotalMilliseconds < historyExpiration) { //search history is valid and has not yet expired... searchString = searchStringHistory + key; } for (int i = 0; i < comboBox.Items.Count; i++) { ((ComboBoxItem)comboBox.Items[i]).Content.ToString().StartsWith(searchString, StringComparison.InvariantCultureIgnoreCase)) { comboBox.SelectedIndex = i; comboBox.Tag = searchStringEnabled + "|" + searchString + "|" + DateTime.Now; break; } } }; #endregion if (!isKeyboardEnabled && enable) { comboBox.Tag = searchStringEnabled + "||"; //Reset the search history on open and close comboBox.DropDownOpened += delegate { comboBox.Tag = searchStringEnabled + "||"; }; comboBox.DropDownClosed += delegate { comboBox.Tag = searchStringEnabled + "||"; }; //Add handler to parent control, so that we search even when combobox is closed, yet focused comboBox.KeyUp += keyPressSearch; for (int i = 0; i < comboBox.Items.Count; i++) { { ((ComboBoxItem)comboBox.Items[i]).KeyUp += keyPressSearch; } } } else if (isKeyboardEnabled && !enable) { //Remove handler comboBox.KeyUp -= keyPressSearch; for (int i = 0; i < comboBox.Items.Count; i++) { { ((ComboBoxItem)comboBox.Items[i]).KeyUp -= keyPressSearch; } } comboBox.Tag = ""; } else { //Remove handler comboBox.KeyUp -= keyPressSearch; comboBox.Tag = ""; } } }