2014-04-11 55 views
1

我有一个ComboBoxDataSource属性设置为这个Type的列表:组合框的DropDownList搜索文本

public class ListInfo 
{ 
    public int Key { get; set; } 
    public string Name { get; set; } 
} 

DropDownStyle设置为DropDownList,我设置了AutoCompleteSourceListItemsAutoCompleteModeSuggestAppend

经过一些测试后,客户端回来并要求能够找到文本值的任何部分,而不仅仅是从文本的开头。我看到的大多数示例都是在DropDownStyle设置为DropDown时执行此操作的,我无法这样做,因为用户无法编辑列表中的内容,只需选择一个值即可。

我试图创建一个CustomSource,但是当我尝试将AutoCompleteMode设置为任意值,我得到了以下信息:可用于

只值AutoCompleteMode.None当DropDownStyle是 ComboBoxStyle。 DropDownList和AutoCompleteSource不是 AutoCompleteSource.ListItems。

我找到了这个AutoSuggestCombo,但我又碰到了问题DropDownStyle

如何,我不是:

  1. 使用ComboBoxDropDownStyle设置为DropDown,不允许最终用户进入新的元素?

  2. 能够搜索ItemsString价值的任何部分,而不仅仅是当前的DropDownList风格使用的StartsWith

这是开始使用的Rx的机会,或者是路线臃肿的解决方案和随之而来的学习曲线? (到目前为止使用简单教程)

回答

2

您必须将所有Autocompletion属性设置为none并自行处理这些内容。 可能有更简单的解决方案,但您可以像这样编写KeyPress事件。

private void comboBox1_KeyPress(object sender, KeyPressEventArgs e) 
{ 
    SortedDictionary<int, ListInfo> dict = new SortedDictionary<int, ListInfo>(); 

    int found = -1; 
    int current = comboBox1.SelectedIndex; 

    // collect all items that match: 
    for (int i = 0; i < comboBox1.Items.Count; i++) 
     if (((ListInfo)comboBox1.Items[i]).Name.ToLower().IndexOf(e.KeyChar.ToString().ToLower()) >= 0) 
     // case sensitive version: 
     // if (((ListInfo)comboBox1.Items[i]).Name.IndexOf(e.KeyChar.ToString()) >= 0) 
       dict.Add(i, (ListInfo)comboBox1.Items[i]); 

    // find the one after the current position: 
    foreach (KeyValuePair<int, ListInfo> kv in dict) 
      if (kv.Key > current) { found = kv.Key; break; } 

    // or take the first one: 
    if (dict.Keys.Count > 0 && found < 0) found = dict.Keys.First(); 

    if (found >= 0) comboBox1.SelectedIndex = found; 

    e.Handled = true; 

} 

您可以决定是否需要区分大小写;可能不是..