闲坐敲棋

有约不来过夜半,闲敲棋子落灯花

导航

c# winform 智能模糊匹配 输入框

Posted on 2009-09-01 23:10  闲坐敲棋  阅读(3704)  评论(1编辑  收藏  举报

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace Tools
{
     public class TextBoxExt : System.Windows.Forms.TextBox
     {

         //private System.ComponentModel.Container components = null;
         private System.Windows.Forms.ListBox m_lstShowChoice = null;
         public TextBoxExt()
         {
             this.Leave += new EventHandler(TextBoxExt_Leave);
             this.KeyDown += new KeyEventHandler(TextBoxExt_KeyDown);
             this.KeyUp += new KeyEventHandler(TextBoxExt_KeyUp);
             this.DoubleClick += new EventHandler(TextBoxExt_DoubleClick);
         }
         private void lstBox_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
         {
             ListBox box = (ListBox)sender;
             if ((box.SelectedIndex > -1) && !this.ReadOnly)
             {

                 this.Text = box.SelectedItem.ToString();
                 //选择后文本框失去了焦点,这里移回来
                 this.Focus();
             }
         }
         private void lstBox_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
         {

             ListBox box = (ListBox)sender;
             Point pt = new Point(e.X, e.Y);
             int n = box.IndexFromPoint(pt);
             if (n >= 0)
                 box.SelectedIndex = n;

         }

         #region 设置提示框的背景

         private Color m_lstForColor = System.Drawing.SystemColors.InfoText;
         private Color m_lstBackColor = System.Drawing.SystemColors.InfoText;

         /// <summary>

         /// 设置/获取提示的背景色

         /// </summary>

         public Color PromptForeColor
         {

             get
             {

                 return m_lstForColor;

             }

             set
             {

                 m_lstForColor = value;

                 //lstPrompt的创建见下面的代码

                 ListBox box = this.lstPrompt;

                 if (box != null)

                     box.BackColor = m_lstForColor;

             }

         }
         public Color PromptBackColor
         {

             get
             {

                 return m_lstBackColor;

             }

             set
             {

                 m_lstBackColor = value;

                 //lstPrompt的创建见下面的代码

                 ListBox box = this.lstPrompt;

                 if (box != null)

                     box.BackColor = m_lstBackColor;

             }

         }

         #endregion
         public System.Windows.Forms.ListBox lstPrompt
         {

             get
             {
                 //如果没有列表用于显示提示的列表框,则创建一个

                 if ((m_lstShowChoice == null) && this.Parent != null)
                 {
                     m_lstShowChoice = new ListBox();
                     m_lstShowChoice.Visible = false;
                     m_lstShowChoice.Left = this.Left;
                     m_lstShowChoice.Top = this.Bottom;
                     m_lstShowChoice.Width = this.Width;
                     m_lstShowChoice.TabStop = false;
                     m_lstShowChoice.Sorted = true;
                     m_lstShowChoice.ForeColor = this.m_lstForColor; //前景
                     m_lstShowChoice.BackColor = this.m_lstBackColor; //背景(参见m_lstForColor的创建
                     m_lstShowChoice.BorderStyle = BorderStyle.FixedSingle;

                     //如果提示框过低,则显示到上面

                     if (m_lstShowChoice.Bottom > this.Parent.Height)

                         m_lstShowChoice.Top = this.Top - m_lstShowChoice.Height + 8;

                     m_lstShowChoice.MouseUp += new System.Windows.Forms.MouseEventHandler(this.lstBox_MouseUp);
                     m_lstShowChoice.MouseMove += new System.Windows.Forms.MouseEventHandler(this.lstBox_MouseMove);

                     this.Parent.Controls.Add(m_lstShowChoice);
                     this.Parent.ResumeLayout(false);
                     m_lstShowChoice.BringToFront();

                 }
                 return m_lstShowChoice;
             }
         }
         private ArrayList m_ForChoice = new ArrayList();
         public ArrayList ChoiceArray
         {
             get
             {
                 return m_ForChoice;
             }
             set
             {
                 m_ForChoice = (ArrayList)(value.Clone());
                 ListBox box = this.lstPrompt;
                 if (box != null)
                 {
                     box.Items.Clear();
                     box.Items.AddRange(m_ForChoice.ToArray());
                 }
             }
         }
         private bool m_AllowSpace = false;

         public bool AllowSpace
         {
             get
             {
                 return m_AllowSpace;
             }
             set
             {
                 m_AllowSpace = value;
             }

         }
         private bool m_bChoiceOnly = false;
         public bool ChoicOnly
         {
             get
             {
                 return this.m_bChoiceOnly;
             }
             set
             {
                 this.m_bChoiceOnly = value;
             }
         }
         private int m_nOldPos = 0;

         private bool bKeyDown = false;

         private string m_strOldText = "";
         private void TextBoxExt_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
         {
             m_nOldPos = this.SelectionStart;
             bKeyDown = true;
             m_strOldText = this.Text;
         }

         private void FillPrompt(string p_strText)
         {
             ListBox box = this.lstPrompt;
             if (box != null)
             {
                 box.Items.Clear();
                 if (p_strText.Length == 0)//没有内容,显示全部
                     box.Items.AddRange(this.ChoiceArray.ToArray());
                 else
                 {
                     foreach (string s in this.ChoiceArray)
                     {
                         if (s.ToLower().IndexOf(p_strText.ToLower()) >= 0)
                             box.Items.Add(s);

                     }
                 }
             }
         }
         private void TextBoxExt_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
         {

             if (!bKeyDown)//忽略掉多余的KeyUp事件
                 return;
             bKeyDown = false;
             ListBox box = this.lstPrompt;
             switch (e.KeyCode)
             {
                 //通过上下箭头在待选框中移动
                 case System.Windows.Forms.Keys.Up:
                 case System.Windows.Forms.Keys.Down:

                     if ((box != null) && !this.Multiline)//多行文本通过上下箭头在两行之间移动
                     {
                         if ((e.KeyCode == System.Windows.Forms.Keys.Up) && (box.SelectedIndex > -1))//↑
                             box.SelectedIndex--;
                         else if ((e.KeyCode == System.Windows.Forms.Keys.Down) && (box.SelectedIndex < box.Items.Count - 1))//↑
                             box.SelectedIndex++;

                         //上下箭头不能移动当前光标,因此,还原原来位置
                         this.SelectionStart = m_nOldPos;

                         //显示提示框
                         if (!box.Visible)
                         {
                             if (box.Width != this.Width)
                                 box.Width = this.Width;
                             box.Visible = true;

                         }
                     }

                     break;

                 case System.Windows.Forms.Keys.Escape://ESC隐藏提示

                     if ((box != null) && box.Visible)
                         box.Hide();
                     break;

                 case System.Windows.Forms.Keys.Return://回车选择一个或跳到下一控件
                     if ((box == null) || this.Multiline)
                         break;

                     //没有显示提示框时,移动到下一控件
                     if (!box.Visible)
                     {
                         SendKeys.Send("{TAB}");
                     }
                     else
                     { //有提示,关闭提示{
                         if (box.SelectedIndex > -1)//有选择,使用当前选择的内容
                             this.Text = box.SelectedItem.ToString();
                         this.SelectionStart = this.Text.Length;
                         this.SelectAll();
                         box.Hide();

                     }
                     break;
                 default: //判断文本是否改变
                     string strText = this.Text;
                     //不允许产生空格,去掉文本中的空格
                     if (!this.AllowSpace)
                         strText = this.Text.Replace(" ", "");
                     int nStart = this.SelectionStart;

                     if (strText != m_strOldText)//文本有改变
                     {

                         //设置当前文本和键盘光标位置
                         this.Text = strText;
                         if (nStart > this.Text.Length)
                             nStart = this.Text.Length;
                         this.SelectionStart = nStart;

                         //修改可供选择的内容,并显示供选择的列表框
                         if (box != null)
                         {
                             FillPrompt(strText);
                             if (!box.Visible)
                             {
                                 if (box.Width != this.Width)
                                     box.Width = this.Width;
                                 box.Visible = true;

                             }
                         }
                     }
                     break;
             }
         }
         private void TextBoxExt_Leave(object sender, EventArgs e)
         {

             //对于只选字段,必须输入同待选相匹配的值

             if (this.ChoicOnly)
             {

                 int nIndex = this.ChoiceArray.IndexOf(this.Text);

                 if (nIndex < 0)

                     this.Text = "";

             }

             //失去焦点后,必须隐藏提示

             ListBox box = this.lstPrompt;

             if (box != null)

                 box.Visible = false;

         }

         private void TextBoxExt_DoubleClick(object sender, EventArgs e)
         {
             if (this.ReadOnly)
                 return;
             ListBox box = this.lstPrompt;
             if ((box != null) && (!box.Visible))
             {
                 if (box.Width != this.Width)
                     box.Width = this.Width;
                 box.Visible = true;
             }
         }
    }
}

------------------------------------------------------------------------
调用

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using Tools;

namespace MyTest
{
    public partial class Form1 : Form
    {
        TextBoxExt txtbox1 = new TextBoxExt();
        public Form1()
        {
            InitializeComponent();
            this.Controls.Add(txtbox1);
            txtbox1.PromptForeColor = Color.Gray;
            txtbox1.PromptBackColor = Color.Snow;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //创建一个数组,用于填充本控件的可选项

            ArrayList arr = new ArrayList();

            arr.Add("好好学习,天天消瘦");

            arr.Add("bbbcccdddeeedsfdfd");

            arr.Add("cdfdccddfdddedfdfeefffdfd");

            arr.Add("ddfdsfddeeefffggg");
           

                txtbox.ChoiceArray = arr;
        }
    }
}