2010-02-13 26 views
13

我试图修改Windows.Forms组合框的行为,以便自动完成下拉菜单根据我指定的规则显示项目。覆盖Winforms组合框自动完成建议规则

默认情况下,如果您在ComboBox中使用自动完成,则遵循的规则是“字符串s包含在下拉列表中,如果(s.StartsWith(userEnteredTextInTheComboBox))”我真正感兴趣的是用新的规则为目前的,但我无法找到它。 (具体来说,我更喜欢s.Contains,而不是s.StartsWith。)

我可以拼凑一个笨拙的解决方案,使用两个控件而不是一个,但我真的会更开心一个实际上做我想做的事。

更新:经过一些更多的搜索后,我发现本质上the same question。在那里提供的答案表明,使用两个控件来“伪造”是要走的路。

回答

17

我有同样的问题,并寻找一个快速解决方案。

最终我最终自己写了。这有点肮脏,但如果需要,它不应该很难变得更漂亮。

这个想法是在每次按键后重新构建组合列表。这样我们就可以依靠组合的内置界面上,我们并不需要自己实现一个文本框和列表框界面...

只记得设置combo.Tagnull如果你重新编译组合的选项列表。

private void combo_KeyPress(object sender, KeyPressEventArgs e) { 
    comboKeyPressed(); 
} 

private void combo_TextChanged(object sender, EventArgs e) { 
    if (combo.Text.Length == 0) comboKeyPressed(); 
} 

private void comboKeyPressed() { 
    combo.DroppedDown = true; 

    object[] originalList = (object[])combo.Tag; 
    if (originalList == null) { 
     // backup original list 
     originalList = new object[combo.Items.Count]; 
     combo.Items.CopyTo(originalList, 0); 
     combo.Tag = originalList; 
    } 

    // prepare list of matching items 
    string s = combo.Text.ToLower(); 
    IEnumerable<object> newList = originalList; 
    if (s.Length > 0) { 
     newList = originalList.Where(item => item.ToString().ToLower().Contains(s)); 
    } 

    // clear list (loop through it, otherwise the cursor would move to the beginning of the textbox...) 
    while (combo.Items.Count > 0) { 
     combo.Items.RemoveAt(0); 
    } 

    // re-set list 
    combo.Items.AddRange(newList.ToArray()); 
} 
+0

我做到了,但我应该搬到这条线“combo.DroppedDown = TRUE;”以成为该功能的最后一行。否则,当试图删除最后一个项目“combo.Items.RemoveAt(0);”时会引发异常 – Ehsan 2017-02-28 13:07:25