Silverlight组合框键盘选择

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Silverlight组合框键盘选择相关的知识,希望对你有一定的参考价值。

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.
  1. string[] state = new string[] { "Alabama", "Alaska", "Arizona", "Arkansas", "Delaware", "Louisiana", "Maine" };
  2.  
  3. ComboBox comboBox = new ComboBox();
  4.  
  5. for (int i = 0; i < state.Length; i++)
  6. {
  7. ComboBoxItem comboBoxItem = new ComboBoxItem();
  8. comboBoxItem.Content = state[i];
  9. comboBox.Items.Add(comboBoxItem);
  10. }
  11.  
  12. //Must enable keyboard selection **AFTER** it all items have bene added to the ComboBox
  13. comboBox.SetKeyboardSelection(true);
  14.  
  15.  
  16. ...
  17.  
  18. public static class Extensions
  19. {
  20. /*
  21.   * SetKeyboardSelection enables keyboard selection on all
  22.   * ComboBoxItems, as well as on the ComboBox itself (it has not already been added).
  23.   * In addition, it tracks the "search history" that is created as the user types.
  24.   * This is done to allow the user to type in more letters to narrow down
  25.   * results (ie. "Ala" = Alabama, Alaska; "Alab" = Alabama)
  26.   */
  27. public static void SetKeyboardSelection(this ComboBox comboBox, bool enable)
  28. {
  29. string searchStringEnabled = "KeyboardSelectionEnabled";
  30. string comboBoxTag = comboBox.Tag==null? "" : comboBox.Tag.ToString();
  31. //See if our search history control already exists by analyzing the combobox tag...
  32. bool isKeyboardEnabled = comboBoxTag.Contains(searchStringEnabled);
  33.  
  34. /*
  35.   * KeyPressSearch is defined as an anonymous delegate, that SetKeyboardSelection delegates
  36.   * to the KeyUp events of ComboBoxItems and the parent ComboBox.
  37.   */
  38. #region KeyPressSearch
  39. KeyEventHandler keyPressSearch = delegate(object sender, KeyEventArgs e)
  40. {
  41. //Since Key has only certain values, A-Z, D0-D9, NumPad0-9, Space, etc. let's just focus on
  42. //letters, and numbers, and ignore all other keys... if they're pressed, clear the search history
  43. //another option is to use PlatformKeyCode, but since it's platform specific, let's not.
  44. string key = e.Key.ToString();
  45. if (key.Length > 1 && (key.StartsWith("D") || key.StartsWith("NumPad")))
  46. { //remove the D/NumPad prefix to get the digit
  47. key = key.Replace("NumPad", "").Replace("D", "");
  48. }
  49. else if (key.Length > 1)
  50. {
  51. comboBox.Tag = searchStringEnabled + "||";
  52. return;
  53. }
  54. string searchHistoryPartsString = comboBox.Tag == null ? searchStringEnabled + "||" : comboBox.Tag.ToString();
  55. string[] searchHistoryParts = (searchHistoryPartsString.Contains("|")) ? searchHistoryPartsString.Split('|') : new string[0];
  56.  
  57. int historyExpiration = 1500; //In 1.5 seconds, clear the history, and start new...
  58. string searchStringHistory = searchHistoryParts.Length == 3 ? searchHistoryParts[1] : "";
  59. string searchStringTimeStampString = searchHistoryParts.Length == 3 ? searchHistoryParts[2] : "";
  60. DateTime searchStringTimeStamp;
  61. string searchString = key;
  62.  
  63. if (DateTime.TryParse(searchStringTimeStampString, out searchStringTimeStamp)
  64. && DateTime.Now.Subtract(searchStringTimeStamp).TotalMilliseconds < historyExpiration)
  65. { //search history is valid and has not yet expired...
  66. searchString = searchStringHistory + key;
  67. }
  68.  
  69. for (int i = 0; i < comboBox.Items.Count; i++)
  70. {
  71. if (comboBox.Items[i].GetType() == typeof(ComboBoxItem) &&
  72. ((ComboBoxItem)comboBox.Items[i]).Content.ToString().StartsWith(searchString, StringComparison.InvariantCultureIgnoreCase))
  73. {
  74. comboBox.SelectedIndex = i;
  75. comboBox.Tag = searchStringEnabled + "|" + searchString + "|" + DateTime.Now;
  76. break;
  77. }
  78. }
  79. };
  80. #endregion
  81.  
  82. if (!isKeyboardEnabled && enable)
  83. {
  84. comboBox.Tag = searchStringEnabled + "||";
  85.  
  86. //Reset the search history on open and close
  87. comboBox.DropDownOpened += delegate
  88. {
  89. comboBox.Tag = searchStringEnabled + "||";
  90. };
  91. comboBox.DropDownClosed += delegate
  92. {
  93. comboBox.Tag = searchStringEnabled + "||";
  94. };
  95.  
  96. //Add handler to parent control, so that we search even when combobox is closed, yet focused
  97. comboBox.KeyUp += keyPressSearch;
  98.  
  99. for (int i = 0; i < comboBox.Items.Count; i++)
  100. {
  101. if (comboBox.Items[i].GetType() == typeof(ComboBoxItem))
  102. {
  103. ((ComboBoxItem)comboBox.Items[i]).KeyUp += keyPressSearch;
  104. }
  105. }
  106. }
  107. else if (isKeyboardEnabled && !enable)
  108. {
  109. //Remove handler
  110. comboBox.KeyUp -= keyPressSearch;
  111. for (int i = 0; i < comboBox.Items.Count; i++)
  112. {
  113. if (comboBox.Items[i].GetType() == typeof(ComboBoxItem))
  114. {
  115. ((ComboBoxItem)comboBox.Items[i]).KeyUp -= keyPressSearch;
  116. }
  117. }
  118. comboBox.Tag = "";
  119. }
  120. else
  121. {
  122. //Remove handler
  123. comboBox.KeyUp -= keyPressSearch;
  124. comboBox.Tag = "";
  125. }
  126. }
  127. }

以上是关于Silverlight组合框键盘选择的主要内容,如果未能解决你的问题,请参考以下文章

ms silverlight blend sketchflow - 组合框中的默认文本

如何使 Silverlight 自定义控件的属性数据可绑定?

Silverlight 组合框 selectedvalue 字符串属性绑定

Silverlight Combobox 将所选项目设置为 datagrid 的所选项目

当组合框打开时,Silverlight Combobox 触发 KeyDown 事件

如何以编程方式将垂直滚动条添加到组合框