zoukankan      html  css  js  c++  java
  • WinForm AutoComplete 输入提示、自动补全

    一、前言

      又临近春节,作为屌丝的我,又要为车票发愁了。记得去年出现了各种12306的插件,最近不忙,于是也着手自己写个抢票插件,当是熟悉一下WinForm吧。小软件还在开发中,待完善后,也写篇博客与大家分享。今天我们的重点不是抢票软件,而是其中的一点功能。我们在买票的时候选站点的自动补全如下图:

    这功能在WinForm里用什么控件来实现呢?

    一、自带控件  

      WinForm里面的ComBoBox 和TextBox 其实是有自带的自动补全功能的,我们只需要将设置相应的属性:
           1、将  AutoCompleteSource 属性设置为 ListItems 或 CustomerSource (textbox 没有 ListItems)
             2、设置 AutoCompleteMode  自动完成样式属性设置,有三值 Suggest(显示相关下拉)、append(自动补全相关)、suggestappend(前两者的结合),这个可以自行试验下。
             3、然后设置 绑定 控件的 DataSource 或 AutoCompleteCustomSource。
         
    AutoCompleteSource属性设置的是 CustomerSource 的时候我们需要绑定 AutoCompleteCustomSource属性的值,值为一个string类型的数组:
                         this.cbbEndStation.AutoCompleteCustomSource.AddRange(new string[] { "站点1", "站点2", "站点3", "站点4" });

          这样ComBoBox 和 TextBox 就有输入提示功能了。至此,不知道大家有没有发现问题,这里绑定的数据只有 显示的值,而没有 实际的值,一般像这种控件,我们都是有一个显示值和一个实际值的。有人可能会说,使用ComBoBox 控件,然后将AutoCompleteSource设置为ListItems,提示的就是DataSource里的值了,而DataSource是可以绑定 集合,设置DisplayMember和ValueMember的。是的,这样可以实现自动提示,并且也能在选中提示的某项时,取到显示的值和实际值。但是这种方式至少有两个缺点:

             1、像购票的站点这种,数据量很大,有2k多条吧,你一次全绑定到ComboBox上?数据量太大,它没有提供相应的事件来过滤数据。

             2、多种搜索方式怎么办?中文、拼音、实际值、都是是可以用来做输入提示的关键字的。

         其实以上两点就是应为 没有提供相应的事件来处理 “搜索”

    二、TextBox+ListBox 自定义AutoComplete

          其实我可以用 TextBox来获得用户的输入,然后动态控制ListBox。下面就按我做的思路一步步来实现一个自定义AutoComplete。

          1、监听 textbox的 keyUp事件,获得用户输入

     1         /// <summary>
     2         /// 站点文本框 键盘按下松开事件
     3         /// </summary>
     4         /// <param name="sender"></param>
     5         /// <param name="e"></param>
     6         private void txtStation_KeyUp(object sender, KeyEventArgs e)
     7         {
     8             TextBox eObj = sender as TextBox; //事件源对象
     9             txtStation_Name = eObj; //当前事件出发对象
    10             if (eObj.Name == "txtStation_S_Name")
    11             {
    12                 txtStation_Value = this.txtStation_S_Value; //保存值的textbox
    13                 ltb_Stations = this.lb_Start_Stations;   //始发站 展示数据的
    14             }
    15             else
    16             {
    17                 //到站 控件
    18                 txtStation_Value = this.txtStation_E_Value; //保存值的textbox
    19                 ltb_Stations = this.lb_End_Stations;   //始发站 展示数据的
    20             }
    21             //上下左右
    22             if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Left)
    23             {
    24                 if (ltb_Stations.SelectedIndex > 0)
    25                     ltb_Stations.SelectedIndex--;
    26             }
    27             else if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Right)
    28             {
    29                 if (ltb_Stations.SelectedIndex < ltb_Stations.Items.Count - 1)
    30                     ltb_Stations.SelectedIndex++;
    31             }
    32             //回车
    33             else if (e.KeyCode == Keys.Enter)
    34             {
    35                 StationInfo info = ltb_Stations.SelectedItem as StationInfo;
    36                 txtStation_Name.Text = info.StationName_CN;
    37                 txtStation_Value.Text = info.StationValue;
    38                 ltb_Stations.Visible = false;
    39             }
    40             else
    41             {
    42 
    43                 if (txtStation_Name.Text != "")
    44                 {
    45                     IList<StationInfo> dataSource = StationInfo.GetStations(txtStation_Name.Text.Trim());
    46                     if (dataSource.Count > 0)
    47                     {
    48                         ltb_Stations.DataSource = dataSource;
    49                         ltb_Stations.DisplayMember = "StationName_CN";
    50                         ltb_Stations.ValueMember = "StationValue";
    51                         ltb_Stations.Visible = true;
    52                     }
    53                     else
    54                         ltb_Stations.Visible = false;
    55                 }
    56                 else
    57                 {
    58                     ltb_Stations.Visible = false;
    59                 }
    60             }
    61             txtStation_Name.Select(txtStation_Name.Text.Length, 1); //光标定位到文本框最后
    62         }
    View Code


          2、监听 ListBox 控件的点击事件
          

     1         /// <summary>
     2         /// 展示站点列表的listbox的点击事件,为了给textbox赋值
     3         /// </summary>
     4         /// <param name="sender"></param>
     5         /// <param name="e"></param>
     6         private void ListBox_StationDatas_Click(object sender, EventArgs e)
     7         {
     8             ListBox eObj = sender as ListBox;
     9             StationInfo info = eObj.SelectedItem as StationInfo;
    10             txtStation_Name.Text = info.StationName_CN;
    11             txtStation_Value.Text = info.StationValue;
    12             eObj.Visible = false;
    13             txtStation_Name.Select(txtStation_Name.Text.Length, 1); //光标定位到最后
    14         }


          3、监听 ListBox 控件的鼠标移动事件

     1          /// <summary>
     2          /// 展示站点列表的listbox, 鼠标在该控件上移动事件,
     3       /// 为了鼠标移动选项
     4       /// </summary>
     5         /// <param name="sender"></param>
     6         /// <param name="e"></param>
     7         private void ListBox_StationDatas_MouseMove(object sender, MouseEventArgs e)
     8         {
     9             ListBox eObj = sender as ListBox;
    10             eObj.SelectedIndex = eObj.IndexFromPoint(e.Location);
    11         }

    以上三步就可以完成一个自定义 AutoComplete的功能了,为什么要叫自定义呢?因为我们在 监听 TextBox 的输入时,可以自定义搜索规则,还有我们可以将ListBox换成 DataGridView都是可以的,灵活性很大,只要按这个思路来就可以。

    三、一些第三方控件

         当然网络上也有一些非常好的类似AutoComplete的第三方控件,这里我就不一一列出来了,因为我没有找到合适的,呵呵!如果有人用过好的,欢迎在评论中分享,谢谢!

    最后附上Demo的源码:点击这里下载!
    demo截图:


    如发现文中有误,或有更好的建议,欢迎指出!

  • 相关阅读:
    Python for Infomatics 第14章 数据库和SQL应用四(译)
    展望2017
    bing的简单英文字典工具
    自我安慰
    Python for Infomatics 第14章 数据库和SQL应用三(译)
    Python for Infomatics 第14章 数据库和SQL应用二(译)
    Python for Infomatics 第14章 数据库和SQL应用一(译)
    希望父亲早日恢复
    Python for Infomatics 第13章 网页服务四(译)
    Python for Infomatics 第13章 网页服务三(译)
  • 原文地址:https://www.cnblogs.com/joey0210/p/3426394.html
Copyright © 2011-2022 走看看