【问题标题】:Autocomplete AND preventing new input - combobox自动完成并防止新输入 - 组合框
【发布时间】:2010-10-04 11:49:38
【问题描述】:

我怎样才能让我的程序的用户输入一个值并让它自动完成,但是,我还要阻止他们输入新数据,因为这会导致数据无法找到(除非你有直接访问数据库)。

有人知道怎么做吗?

不只使用下拉式组合框的原因是,通过键入数据来输入数据,然后拒绝列表中不属于选项的字符,因为这样对用户来说更容易。

如果你用过 Quickbook 的 Timer,那就是我想要的组合框样式。

【问题讨论】:

  • 只是出于好奇,为什么要让组合框可编辑,如果您要准确控制可以放入和不能放入的内容?只需将 DropDownStyle 更改为 DropDownList。
  • 因为我希望用户能够输入输入,因为这对用户来说更容易。你用过 QuickBook 的 Timer 吗?我想要这样的东西。

标签: c# .net winforms combobox autocomplete


【解决方案1】:

感谢 BFree 的帮助,但这是我一直在寻找的解决方案。 ComboBox 使用 DataSet 作为源,因此它不是自定义源。

    protected virtual void comboBoxAutoComplete_KeyPress(object sender, KeyPressEventArgs e) {
        if (Char.IsControl(e.KeyChar)) {
            //let it go if it's a control char such as escape, tab, backspace, enter...
            return;
        }
        ComboBox box = ((ComboBox)sender);

        //must get the selected portion only. Otherwise, we append the e.KeyChar to the AutoSuggested value (i.e. we'd never get anywhere)
        string nonSelected = box.Text.Substring(0, box.Text.Length - box.SelectionLength);

        string text = nonSelected + e.KeyChar;
        bool matched = false;
        for (int i = 0; i < box.Items.Count; i++) {
            if (((DataRowView)box.Items[i])[box.DisplayMember].ToString().StartsWith(text, true, null)) {
                matched = true;
                break;
            }
        }

        //toggle the matched bool because if we set handled to true, it precent's input, and we don't want to prevent
        //input if it's matched.
        e.Handled = !matched;
    }

【讨论】:

  • 帮自己一个忙,在方法的顶部执行以下操作:ComboBox comboBox = sender as ComboBox。然后你就不必再铸造 1000 次了。投射 == 开销。
  • 我正在寻找这个确切的东西。但是,上述解决方案无济于事。我仍然无法将下拉列表中的文本限制为列表项。我可能做错了什么?
  • 我不知道,但我已经改变了它,所以也许这个版本会更好。
  • 为什么不用if (box.FindString(text) = -1) { e.Handled = true; } 而不是for 循环?似乎对我有用,而且我认为它更具可读性。
【解决方案2】:

这是我的解决方案,我遇到了同样的问题,并使用文本框而不是组合框修改您的代码以适应我的解决方案,同时为了避免在比较第一个字符串后出现否定响应,在再次与自动完成列表比较之前必须取消选择文本,在这段代码中是一个 AutoCompleteStringCollection shiper,我希望这个解决方案会有所帮助

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
  String text = ((TextBox)sender).Text.Substring(
    0, ((TextBox)sender).SelectionStart) + e.KeyChar;
  foreach(String s in this.shippers)
    if (s.ToUpperInvariant().StartsWith(text.ToUpperInvariant()) ||
      e.KeyChar == (char)Keys.Back || e.KeyChar == (char)Keys.Delete)
        return;                    

  e.Handled = true;
}

【讨论】:

    【解决方案3】:

    好的,这就是我想出的。黑客?也许吧,但是,嘿,它有效。我只是用一周中的几天填充组合框(嘿,我需要一些东西),然后处理按键事件。每次按键时,我都会检查该单词是否与 AutoCompleteSourceCollection 中任何单词的开头相匹配。如果没有,我将 e.Handled 设置为 true,因此不会注册密钥。

        public Form5()
        {
            InitializeComponent();
    
            foreach (var e in Enum.GetValues(typeof(DayOfWeek)))
            {
                this.comboBox1.AutoCompleteCustomSource.Add(e.ToString());
            }
    
            this.comboBox1.KeyPress += new KeyPressEventHandler(comboBox1_KeyPress);
    
        }
    
        private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            string text = this.comboBox1.Text + e.KeyChar;
            e.Handled =  !(this.comboBox1.AutoCompleteCustomSource.Cast<string>()
               .Any(s => s.ToUpperInvariant().StartsWith(text.ToUpperInvariant()))) && !char.IsControl(e.KeyChar);
        }
    

    编辑:如果您使用的是 .Net 3.5,则需要参考 System.Linq。如果您使用的是 .NET 2.0,请改用它:

        private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            string text = this.comboBox1.Text + e.KeyChar;
           foreach (string s in this.comboBox1.AutoCompleteCustomSource)
            {
                if (s.ToUpperInvariant().StartsWith(text.ToUpperInvariant()))
                {
                    return;
                }
            }
            e.Handled = true;
    
        }
    

    【讨论】:

    • 错误 1 ​​'System.Windows.Forms.AutoCompleteStringCollection' 不包含 'Cast' 的定义,并且没有扩展方法 'Cast' 接受类型为 'System.Windows.Forms.AutoCompleteStringCollection' 的第一个参数可以找到(您是否缺少 using 指令或程序集引用?)
    • 我有 .NET 3.5 SP1 但我没有 System.Linq
    • 我正在使用 VS 2008 和 .NET 3.5
    • 啊项目属性已将此项目设置为目标 .NET 2.0
    • 不,我没有使用 CustomSource,而且 AutoCompleteSource 似乎没有充当数组...正在寻找解决方法。
    【解决方案4】:

    我知道我迟到了大约六年,但也许这可以帮助某人。

        private void comboBox1_Leave(object sender, EventArgs e)
        {
            if (comboBox1.Items.Contains(comboBox1.Text)) { MessageBox.Show("YE"); }
            else { MessageBox.Show("NE"); }
    
            OR
    
            if (comboBox1.FindStringExact(comboBox1.Text) > -1) { MessageBox.Show("YE"); }
            else { MessageBox.Show("NE"); }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-10
      相关资源
      最近更新 更多