可以搜索的ComboBox

在.Net的技术论坛里,有一次看到了某网友发了个帖子,大概的意思就是:假如数据库中有很多的记录读取到ComboBox中,恰好是大于1000条记录,如果要选择其中第500条记录,那不得烦死了啊?所以,最好是输入代码或者其他的助记符号就马上可以找到那条记录.

为此,我作了一个控件SearchComboBox.由于本人表达能力有限,不怎么好,就直接开始程序了

首先,建立一个项目Hexudong_ComboBox

然后添加一个类ItemName,具体代码如下

ItemName.cs

using System;

namespace Hexudong_ComboBox
{
    /// <summary>
    /// ItemName 的摘要说明。
    /// </summary>
    public class ItemName:object
    {
        private long _ID;
        private string _Code;
        private string _Name;
        private string _PinYinCode;
        private string _WuBiCode;
        private string _DefineCode;
        private string _Text;

        public ItemName()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }

        public ItemName(long id,string code,string name)
        {
            _ID=id;
            _Code=code;
            _Name=name;
            _Text=_Code + " " + _Name;
        }

        public ItemName(long id,string code,string name,string pinyincode,string wubicode)
        {
            _ID=id;
            _Code=code;
            _Name=name;
            _PinYinCode=pinyincode;
            _WuBiCode=wubicode;
            _Text=_Code + " " + _Name;
        }

        public ItemName(long id,string code,string name,string pinyincode,string wubicode,string definecode)
        {
            _ID=id;
            _Code=code;
            _Name=name;
            _PinYinCode=pinyincode;
            _WuBiCode=wubicode;
            _DefineCode=definecode;
            _Text=_Code + " " + _Name;
        }

        /// <summary>
        /// ID号
        /// </summary>
        public long ID
        {
            get
            {
                return _ID;
            }
            set
            {
                _ID=value;
            }
        }

        /// <summary>
        /// 代码
        /// </summary>
        public string Code 
        {
            get
            {
                return _Code;
            }
            set
            {
                _Code=value;
            }
        }

        /// <summary>
        /// 名称
        /// </summary>
        public string Name
        {
            get
            {
                return _Name;
            }
            set
            {
                _Name=value;
            }
        }

        /// <summary>
        /// 拼音码
        /// </summary>
        public string PinYinCode
        {
            get
            {
                return _PinYinCode;
            }
            set
            {
                _PinYinCode=value;
            }
        }

        /// <summary>
        /// 五笔码
        /// </summary>
        public string WuBiCode
        {
            get
            {
                return _WuBiCode;
            }
            set
            {
                _WuBiCode=value;
            }
        }

        /// <summary>
        /// 自定义码
        /// </summary>
        public string DefineCode
        {
            get
            {
                return _DefineCode;
            }
            set
            {
                _DefineCode=value;
            }
        }

        /// <summary>
        /// 控件文本
        /// </summary>
        public string Text
        {
            get
            {
                return _Text;
            }
            set
            {
                _Text = value;
            }
        }

        /// <summary>
        /// 重写ToString方法
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return _Text;
        }
    }
}

再添加一个类SearchComboBox,具体的代码如下:

SearchComboBox.cs

using System;
using System.Windows.Forms;
using System.Drawing;

namespace Hexudong_ComboBox
{
    /// <summary>
    /// SearchCombBox 的摘要说明。
    /// </summary>
    public class SearchComboBox : System.Windows.Forms.ComboBox
    {
        public SearchComboBox()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
            DrawMode = DrawMode.OwnerDrawFixed;
        }

        //根据输入文本框内容的Code查找相应的名称值并显示为代码+名称的字符串
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                foreach (object obj in Items)
                {
                    ItemName item = (ItemName)obj;
                    if (item.Code.Trim() == Text.Trim())
                    {
                        SelectedItem = item;
                        Text = item.Code + " " + item.Name;
                        break;
                    }
                }
            }
            base.OnKeyPress(e);
        }

        //失去焦点
        protected override void OnLostFocus(EventArgs e)
        {
            GetText(false);
            base.OnLostFocus(e);
        }

        //得到焦点
        protected override void OnGotFocus(EventArgs e)
        {
            GetText(true);
            base.OnGotFocus(e);
        }

        //选择项改变
        protected override void OnSelectedIndexChanged(EventArgs e)
        {
            GetText(true);
            base.OnSelectedIndexChanged(e);
        }

        /// <summary>
        /// 失去焦点,得到焦点,选择变化时的文本内容
        /// </summary>
        /// <param name="Focused">是否聚焦,主要区别于OnLostFocus事件</param>
        /// <returns></returns>
        private string GetText(bool Focused)
        {
            if (SelectedItem != null)
            {
                ItemName item = (ItemName)SelectedItem;
                if (Focused)
                {
                    Text = item.Code + " " + item.Name;
                    SelectAll();
                }
                else
                {
                    Text = item.Name;
                }
            }
            else
            {
                Text = "";
            }
            return Text;
        }

        //重画下拉子项的内容,主要是赋文本内容
        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            e.DrawBackground();
            e.DrawFocusRectangle();

            if (e.Index < 0)
                e.Graphics.DrawString("", e.Font,
                 new SolidBrush(e.ForeColor), e.Bounds.X, e.Bounds.Y);
            else
            {
                if (Items[e.Index].GetType() == typeof(ItemName))
                {
                    ItemName item = (ItemName)Items[e.Index];
                    e.Graphics.DrawString(item.Text,
                     e.Font, new SolidBrush(e.ForeColor), e.Bounds.X, e.Bounds.Y);
                }
                else
                {
                    e.Graphics.DrawString("",
                     e.Font, new SolidBrush(e.ForeColor), e.Bounds.X, e.Bounds.Y);

                }
            }
            base.OnDrawItem(e);
        }

        /// <summary>
        /// 设置或获取选择项的ID号
        /// </summary>
        public long SelectedID
        {
            get
            {
                if (SelectedItem != null)
                {
                    ItemName item = (ItemName)SelectedItem;
                    return item.ID;
                }
                else
                {
                    return -1;
                }
            }
            set
            {
                int i = 0;
                foreach (object obj in Items)
                {
                    ItemName item = (ItemName)obj;
                    if (item.ID == value)
                    {
                        SelectedItem = item;
                        Text = item.Code + " " + item.Name;
                        break;
                    }
                    if (i == Items.Count - 1)
                    {
                        SelectedItem = null;
                        Text = "";
                    }
                    i++;
                }
            }
        }

        /// <summary>
        /// 设置或获取选择项的代码
        /// </summary>
        public string SelectedCode
        {
            get
            {
                if (SelectedItem != null)
                {
                    ItemName item = (ItemName)SelectedItem;
                    return item.Code;
                }
                else
                {
                    return "";
                }
            }
            set
            {
                int i = 0;
                foreach (object obj in Items)
                {
                    ItemName item = (ItemName)obj;
                    if (item.Code.Trim() == value.Trim())
                    {
                        SelectedItem = item;
                        Text = item.Code + " " + item.Name;
                        break;
                    }
                    if (i == Items.Count - 1)
                    {
                        SelectedItem = null;
                    }
                    i++;
                }
            }
        }

        /// <summary>
        /// 设置或获取选择项的名称
        /// </summary>
        public string SelectedName
        {
            get
            {
                if (SelectedItem != null)
                {
                    ItemName item = (ItemName)SelectedItem;
                    return item.Name;
                }
                else
                {
                    return "";
                }
            }
            set
            {
                int i = 0;
                foreach (object obj in Items)
                {
                    ItemName item = (ItemName)obj;
                    if (item.Name.Trim() == value.Trim())
                    {
                        SelectedItem = item;
                        Text = item.Code + " " + item.Name;
                        break;
                    }
                    if (i == Items.Count - 1)
                    {
                        SelectedItem = null;
                    }
                    i++;
                }
            }
        }
    }
}

最后,编译成类库Hexudong_ComboBox.dll

下面来测试一下刚作的Hexudong_ComboBox.dll

另外建立一个测试的项目,然后把这个Hexudong_ComboBox.dll添加到工具箱中

拖一个到测试界面Form1上,然后,就可以在代码中添加数据到SearchComboBox中

Form1.cs中的部分代码

.........

using Hexudong_ComboBox;

.........

private void Form1_Load(object sender, System.EventArgs e)
{
    this.searchComboBox1.Items.Clear();
    Users objUsers=new UsersS().GetUsers();
    foreach(User objUser in objUsers)
    {
        this.searchComboBox1.Items.Add(new ItemName(objUser.ID,objUser.Code,objUser.Name));
    }

........

聚焦的时候是这样的:

combox1_1

失焦的时候是这样的:

combox1_2

如果你输入003,然后敲回车,那么会出现

combox1_3

好了,实现了功能,结束了

当然,本人还是在学习阶段,或许上面的代码写的不怎么好,希望指正.有些功能还不够强,请扩展,谢谢!

Contributors: FHL