覆盖 Winforms ComboBox 自动完成建议规则
Posted
技术标签:
【中文标题】覆盖 Winforms ComboBox 自动完成建议规则【英文标题】:Override Winforms ComboBox Autocomplete Suggest Rule 【发布时间】:2011-01-16 13:47:30 【问题描述】:我正在尝试修改 Windows.Forms ComboBox 的行为,以便自动完成下拉菜单根据我指定的规则显示项目。
默认情况下,如果您在 ComboBox 中使用 AutoComplete,则遵循的规则是“字符串 s 包含在下拉列表中 if(s.StartsWith(userEnteredTextInTheComboBox))”我真正感兴趣的只是替换一个新规则对于当前的,但我无法找到它。 (具体来说,我更喜欢 s.Contains 而不是 s.StartsWith。)
我可以使用两个控件而不是一个控件来拼凑一个笨拙的解决方案,但我真的会更高兴有一个能真正做到我想要的。
更新:经过更多搜索,我基本上找到了the same question。那里提供的答案表明使用两个控件来“伪造”是要走的路。
【问题讨论】:
【参考方案1】:我遇到了同样的问题,正在寻找快速解决方案。
最后我自己写了。它有点脏,但如果需要的话,让它变得更漂亮应该不难。
这个想法是在每次按键后重新构建组合列表。这样我们就可以依赖combo的内置接口了,我们不需要用文本框和列表框来实现我们自己的接口...
如果您重新构建组合的选项列表,请记住将 combo.Tag
设置为 null
。
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());
【讨论】:
我做到了,但我应该移动这一行“combo.DroppedDown = true;”为了成为函数的最后一行。否则在尝试删除最后一项“combo.Items.RemoveAt(0);”时会引发异常 我收到一个异常,抱怨在组合上设置数据源属性时无法删除项目 @kuklei 这不能通过数据绑定组合完成;像答案一样手动填充项目【参考方案2】:在 Windows Vista 之前,自动完成对象match candidates with prefix only,所以你需要cook your own。
如果您需要在建议列表可见时重置它,use IAutoCompleteDropDown::ResetEnumerator。
【讨论】:
如何在 c# 中为 winforms 编写【参考方案3】:感谢 Ehsan。 仅供参考。我最终得到了这个。
private void comboBoxIdentification_TextChanged(object sender, EventArgs e)
if (comboBoxIdentification.Text.Length == 0)
comboBoxIdentificationKeyPressed(comboBoxIdentification, comboBoxIdentification.Text);
private void comboBoxIdentificationKeyPressed(ComboBox comboBoxParm, string text )
comboBoxParm.DroppedDown = true;
object[] originalList = (object[])comboBoxParm.Tag;
if (originalList == null)
// backup original list
originalList = new object[comboBoxParm.Items.Count];
comboBoxParm.Items.CopyTo(originalList, 0);
comboBoxParm.Tag = originalList;
// prepare list of matching items
string s = 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 (comboBoxParm.Items.Count > 0)
comboBoxParm.Items.RemoveAt(0);
var newListArr = newList.ToArray();
// re-set list
comboBoxParm.Items.AddRange(newListArr);
【讨论】:
以上是关于覆盖 Winforms ComboBox 自动完成建议规则的主要内容,如果未能解决你的问题,请参考以下文章
C# - Winforms - Combobox - 避免选择更新数据源的第一项
为什么在datagridview中对combobox使用自动完成时有两个列表?
当 DataSource 值更改时,WinForms ComboBox 中的项目不会更新