【问题标题】:Override Winforms ComboBox Autocomplete Suggest Rule覆盖 Winforms ComboBox 自动完成建议规则
【发布时间】:2011-01-16 13:47:30
【问题描述】:

我正在尝试修改 Windows.Forms ComboBox 的行为,以便自动完成下拉菜单根据我指定的规则显示项目。

默认情况下,如果您在 ComboBox 中使用 AutoComplete,则遵循的规则是“字符串 s 包含在下拉列表中 if(s.StartsWith(userEnteredTextInTheComboBox))”我真正感兴趣的只是替换一个新规则对于当前的,但我无法找到它。 (具体来说,我更喜欢 s.Contains 而不是 s.StartsWith。)

我可以使用两个控件而不是一个控件来拼凑一个笨拙的解决方案,但我真的会更高兴有一个能真正做到我想要的。

更新:经过更多搜索,我基本上找到了the same question。那里提供的答案表明使用两个控件来“伪造”是要走的路。

【问题讨论】:

    标签: c# winforms combobox autocomplete


    【解决方案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);
        }
    

    【讨论】:

      猜你喜欢
      • 2012-01-27
      • 2017-09-24
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-08
      • 1970-01-01
      • 2012-07-31
      相关资源
      最近更新 更多