zoukankan      html  css  js  c++  java
  • winform 实现TextBox 关键字智能提示

      有时候由于项目需求的需要,需要实现像百度那样输入关键字后有下拉框提示,在网上搜了下,一种是利用ComboBox和TextBox的AutoCompleteMode属性,个人感觉不太灵活,关键字只能从第一个字符开始匹配,不能实现任意位置的匹配和多个关键字的匹配;另外一一种方法是重写listbox 感觉太复杂……

      最后我自己想了个比较简单,灵活的方法:

      使用listBox的DrawMode.OwnerDrawFixed属性,设置ItemHeight=30,添加listBox1_DrawItem事件

    代码
       private static readonly string ConnectionString = ConfigurationManager.ConnectionStrings["SQLConnString"].ConnectionString;
           
    private void Form1_Load(object sender, EventArgs e)
            {
                listBox1.DrawMode
    = DrawMode.OwnerDrawFixed;
                listBox1.ItemHeight
    = 30;

            }
    代码
      private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
            {
               
    // Set the DrawMode property to draw fixed sized items.
                listBox1.DrawMode = DrawMode.OwnerDrawFixed;
               
    // Draw the background of the ListBox control for each item.
                e.DrawBackground();
               
    // Define the default color of the brush as black.
                Brush myBrush = Brushes.Black;
                FontFamily fontFamily
    = new FontFamily("宋体");

                System.Drawing.Font myFont
    = new Font(fontFamily, 20);

               
    // Determine the color of the brush to draw each item based on the index of the item to draw .

               
    if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
                {
                   
    //e.Graphics.FillRectangle(Brushes.Blue, e.Bounds);
                    if (e.Index > -1)
                    {
                        e.Graphics.DrawString(listBox1.Items[e.Index].ToString(), myFont, Brushes.White, e.Bounds, StringFormat.GenericDefault);
                    }

                }
               
    else
                {
                   
    //e.Graphics.FillRectangle(Brushes.White, e.Bounds);
                    if (e.Index > -1)
                    {
                        e.Graphics.DrawString(listBox1.Items[e.Index].ToString(), myFont, myBrush, e.Bounds, StringFormat.GenericDefault);
                    }

                }
                e.DrawFocusRectangle();

            }

        以SQL Server2005示例数据库AdventureWorks为例,添加textBox1_TextChanged事件,获取输入关键字,通过模糊查询将数据库中的相关信息绑定到下拉框listBox1中:

    代码
           private void BindList(DataTable dt)
            {
               
    this.listBox1.Items.Clear();

               
    for (int i = 0; i < dt.Rows.Count; i++)
                {
                    listBox1.Items.Add(dt.Rows[i][
    "name"].ToString());

                }

               
    if (dt.Rows.Count < 11)
                {
                   
    this.listBox1.Height = 30 * dt.Rows.Count + 30;
                }
               
    else
                {
                   
    this.listBox1.Height = 300;
                }



               
    this.listBox1.Visible = true;
            }


           
    private DataTable getDataTable(string s)
            {
               
    string sql = @" SELECT Name FROM   Person.CountryRegion where [Name] like '%" + s.Trim() + "%' ";

               
    string strErr = "";
                DataTable dt
    = new DataTable();

                RunSQL(sql,
    null, out dt, out strErr);
               
    return dt;

            }

           
    public static bool RunSQL(string strSQL, SqlParameter[] para, out DataTable objDataTable, out string strErr)
            {
                objDataTable
    = new DataTable();

                strErr
    = "";

               
    using (SqlConnection conn = new SqlConnection(ConnectionString))
                {

                    SqlCommand sqlComm
    = new SqlCommand(strSQL, conn);
                    sqlComm.CommandType
    = CommandType.Text;

                   
    if (para != null)
                    {
                       
    foreach (SqlParameter parm in para)
                        {
                           
    if ((parm.Direction == ParameterDirection.InputOutput || parm.Direction == ParameterDirection.Input) &&
                                    (parm.Value
    == null))
                            {
                                parm.Value
    = DBNull.Value;
                            }

                            sqlComm.Parameters.Add(parm);
                        }
                    }

                    SqlDataAdapter sqlDa
    = new SqlDataAdapter();
                   
    try
                    {
                        sqlDa.SelectCommand
    = sqlComm;
                        sqlDa.Fill(objDataTable);
                        sqlComm.Parameters.Clear();
                       
    return true;

                    }
                   
    catch (Exception ex)
                    {
                        strErr
    = ex.Message;
                       
    return false;
                    }
                   
    finally
                    {
                       
    if (sqlComm != null)
                        {
                            sqlComm.Dispose();
                        }
                       
    if (sqlDa != null)
                        {
                            sqlDa.Dispose();
                        }
                    }
                }
            }

           
    private void textBox1_TextChanged(object sender, EventArgs e)
            {
               
    if (this.textBox1.Text.Trim() != "")
                {
                    DataTable dt
    = getDataTable(this.textBox1.Text.Trim());
                    BindList(dt);
                   
    this.listBox1.Visible = true;
                }
               
    else
                {
                   
    this.listBox1.Items.Clear();
                   
    this.listBox1.Visible = false;
                }
            }

    在listBox1显示关键字的匹配结果时,先将 this.listBox1.Visible = false;当有匹配结果时置为true,就可以实现当关键字有匹配项时出现下拉提示,没有时隐藏,然后定义listbox和textbox的鼠标事件,使鼠标经过时变色,效果就跟百度的下拉提示一样了

    代码
      private void listBox1_KeyDown(object sender, KeyEventArgs e)
            {
               
    if (e.KeyCode == Keys.Enter && this.listBox1.Visible && this.listBox1.SelectedItems.Count > 0)
                {
                   
    this.textBox1.Text = this.listBox1.SelectedItems[0].ToString();

                   
    this.listBox1.Visible = false;
                   
    this.textBox1.Focus();
                }
            }

           
    private void textBox1_KeyDown(object sender, KeyEventArgs e)
            {
               
    if (e.KeyCode == Keys.Down && this.listBox1.Visible)
                {
                   
    this.listBox1.Focus();

                   
    if (this.listBox1.SelectedItems.Count > 0)
                    {
                       
    this.listBox1.SetSelected(this.listBox1.SelectedIndex, false);
                    }

                   
    if (this.listBox1.Items.Count > 0)
                    {
                       
    this.listBox1.SetSelected(0, true);

                    }


                }
            }

           
    private void listBox1_MouseUp(object sender, MouseEventArgs e)
            {
               
    if (this.listBox1.SelectedItems.Count > 0)
                {
                   
    this.textBox1.Text = this.listBox1.SelectedItems[0].ToString();

                   
    this.listBox1.Visible = false;
                   
    this.textBox1.Focus();
                }
            }


           
    private void listBox1_MouseMove(object sender, MouseEventArgs e)
            {
                Point m
    = new Point(e.X, e.Y);

               
    int index = GetItemAt(this.listBox1, e.X, e.Y);
               
    if (this.listBox1.SelectedItems.Count > 0 && this.listBox1.SelectedIndex != index)
                {

                   
    this.listBox1.SetSelected(this.listBox1.SelectedIndex, false);
                }
               
    if (index != -1 && this.listBox1.SelectedIndex != index)
                {

                   
    this.listBox1.SetSelected(index, true);
                }


            }

           
    private int GetItemAt(ListBox listBox, int X, int Y)
            {
               
    int index = -1;
               
    for (int i = 0; i < listBox.Items.Count; i++)
                {
                    System.Drawing.Rectangle r
    = listBox.GetItemRectangle(i);
                   
    if (r.Contains(new Point(X, Y)))
                    {
                        index
    = i;
                       
    break;
                    }
                }
               
    return index;
            }

    最后的效果:

      

      

     

    code下载

  • 相关阅读:
    CodeForces1152CNeko does Maths
    π的计算公式
    IFS变量对加双引号和不加双引号变量的区别对待
    各种距离
    ADO.NET Data Service 二 绑定数据类
    向客户端注入JavaScript代码
    Ajax ModelPopu and Progress 示例学习
    Sliverlight 入门教程七
    (牛人莫入)Jquery plugin 多文件上传
    自定义控件的验证使用
  • 原文地址:https://www.cnblogs.com/luoht/p/1682930.html
Copyright © 2011-2022 走看看