65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 自动完成组合框

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.45/5 (28投票s)

2003年4月15日

1分钟阅读

viewsIcon

302484

downloadIcon

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 - 第一个发布版本
© . All rights reserved.