C# 自动完成组合框






4.45/5 (28投票s)
2003年4月15日
1分钟阅读

302484

5398
一个C#实现的自动完成组合框,基于Chris Maunder的MFC代码
引言
我需要创建一个在用户输入时自动完成的组合框控件。我在Code Project的优秀资源中搜索,找到了Chris Maunder的一个示例,是用MFC编写的。
我的要求是我想为我的项目使用完全托管的代码,并且由于Chris的控件是用MFC编写的,我决定基于他的代码自己编写一个。我为这个控件添加了一个额外的属性,该属性将控件限制在项目列表中。
控件的所有魔术都发生在OnTextChanged事件中。 _inEditMode字段在OnKeyDown事件中设置,基于是否按下了退格键或删除键。如果该字段为true,则代码会找到部分字符串,选择用户已经输入的部分。
OnValidating被重写,以便在LimitToList属性为true的情况下触发一个NotInList事件,允许用户在用户输入列表中不存在的文本时执行某些操作。
OnNotInList也提供了一个protected virtual方法,以便派生类可以在不订阅其事件的情况下调用事件处理程序。
源代码
using System;
using System.Windows.Forms;
using System.ComponentModel;
namespace MattBerther.Controls
{
    public class AutoCompleteComboBox : System.Windows.Forms.ComboBox
    {
        public event System.ComponentModel.CancelEventHandler NotInList;
        private bool _limitToList = true;
        private bool _inEditMode = false;
        public AutoCompleteComboBox() : base()
        {
        }
        [Category("Behavior")]
        public bool LimitToList
        {
            get { return _limitToList; }
            set { _limitToList = value; }
        }
        protected virtual void 
            OnNotInList (System.ComponentModel.CancelEventArgs e)
        {
            if (NotInList != null)
            {
                NotInList(this, e);
            }
        }   
        protected override void OnTextChanged(System.EventArgs e)
        {
            if (_inEditMode)
            {
                string input = Text;
                int index = FindString(input);
                if (index >= 0)
                {
                    _inEditMode = false;
                    SelectedIndex = index;
                    _inEditMode = true;
                    Select(input.Length, Text.Length);
                }
            }
            base.OnTextChanged(e);
        }
        protected override void 
            OnValidating(System.ComponentModel.CancelEventArgs e)
        {
            if (this.LimitToList)
            {
                int pos = this.FindStringExact(this.Text);
        
                if (pos == -1)
                {
                    OnNotInList(e);
                }
                else
                {
                    this.SelectedIndex = pos;
                }
            }
            base.OnValidating(e);
        }
        protected override void 
            OnKeyDown(System.Windows.Forms.KeyEventArgs e)
        {
            _inEditMode = 
                (e.KeyCode != Keys.Back && e.KeyCode != Keys.Delete);
            base.OnKeyDown(e);
        }
    }
}
使用此控件
以与使用常规System.Windows.Forms.ComboBox相同的方式使用此控件。通过设计器或以编程方式将其添加到您的窗体中,如下所示。
protected override void OnLoad(System.EventArgs e)
{
    base.OnLoad(e);
    MattBerther.Controls.AutoCompleteComboBox cb = new 
        MattBerther.Controls.AutoCompleteComboBox();
    cb.Items.Add("Apples");
    cb.Items.Add("Oranges");
    cb.Items.Add("Grapefruits");
    cb.LimitToList = true;
    cb.NotInList += new CancelEventHandler(combobox_NotInList);
    this.Controls.Add(cb);
}
private void combobox_NotInList(object sender, CancelEventArgs e)
{
    MessageBox.Show("You entered a value that was not 
        consistent with the list provided. Please try again.");
    e.Cancel = true;
}
再次感谢Chris Maunder提供的优秀起点,让我能够用完全托管的代码实现自己的自动完成组合框。
历史
- 1.0 - 04.15.2003 - 第一个发布版本
