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截图:


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

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
我们在使用WinForm中的TextBox的智能提示要使用到两个重要的TextBox属性, 一个是AutoCompleteMode,另一个是AutoCompleteSource。 AutoCompleteMode有四个值,分别是None,Append,Suggest,SuggestAppend。他们分别是:不给提示。最可能的匹配项自动追加到当前数据。产生由一个或多个建议完成字符串组成的下拉列表。最可能的匹配项自动追加到当前数据并产生由一个或多个建议完成字符串组成的下拉列表。 AutoCompleteSource属性允许您从一些系统源中进行选择,例如 FileSystem、HistoryList、RecentlyUsedList、AllUrl 和 CustomSource。如果选择 CustomSource,则必须向 AutoCompleteCustomSource属性提供一个字符串列表。 我们现在就开始 在VS中建一个新的项目,在From1中添加一个TextBox 并取名为TB_AutoComplete。再添加一个BackgroundWorker取名为bgWorker。 接下来的事都由代码完成。 public Form1() {     bgWorker.RunWorkerAsync();//打开异步操作,完成数据的读取     TB_AutoComplete.AutoCompleteMode = AutoCompleteMode.SuggestAppend; //最可能的匹配项自动追加到当前数据并产生由一个或多个建议完成字符串组成的下拉列表     TB_AutoComplete.AutoCompleteSource = AutoCompleteSource.CustomSource; //设置智能提示的源为自定义源    } AutoCompleteStringCollection GetDataFromDB() { AutoCompleteStringCollection ac = new AutoCompleteStringCollection(); string constr = "server=.;initial catalog=AutoComplete;integrated security=true"; //数据库连接 SqlConnection con = new SqlConnection(constr); string sql = "select * from AutoComplete" ; //我这里使用一个叫AutoComplete的数据库,数据库里有两个字段 一个ID,一个AutoComplete。用于存放智能提示的内容    SqwlCommand cmd = new SqlCommand(sql, con); try { con.Open(); SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { string text = reader.GetString(0); ac.Add(text); } con.Close(); } catch (Exception ee) { con.Close(); MessageBox.Show("程序出错了,错误原因是:\n" + ee.Message, "温馨提示"); } return ac; } 然后我们在设计页面中找到bgWorker 在他的DoWorkg事件中写入   private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { e.Result=GetDataFromDB(); } 在RunWorkerCompleted事件中写入 private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { TB_AutoComplete.AutoCompleteCustomSource = (AutoCompleteStringCollection)e.Result; } 这样我们的智能提示就完成 了 效果图看附件
WinForm是微软公司的一种用于创建Windows桌面应用程序的开发工具。WinForm自动补全是指在编写WinForm应用程序时,通过自动补全功能来简化和加快代码编写的过程。 WinForm自动补全功能主要有以下几个方面: 1. 代码自动补全:当编写代码时,通过键入部分代码后使用快捷键(例如Tab键)触发自动补全功能,系统会自动弹出相关的选项供选择。这样可以减少手动敲击代码的工作量,并提高开发效率。 2. 类型和成员的自动提示:在编写代码时,当键入一个对象名或者方法名后,系统会自动弹出相关的类型和成员列表供选择。这可以帮助开发者快速找到需要使用的类型或成员,避免了手动查找的麻烦。 3. 参数提示:当在调用方法或函数时,系统会自动弹出相关参数的提示信息,包括参数名称、类型、默认值等。这可以帮助开发者准确地输入参数,并且避免了因为参数错误引发的运行错误。 4. 括号补全:在编写代码时,当输入一个左括号时,系统会自动插入相应的右括号,并将光标定位在括号之间。这个功能可以帮助开发者快速完成括号的匹配。 总之,WinForm自动补全功能在开发过程中起到了简化代码编写、提高开发效率的作用。它可以帮助开发者减少手动敲击代码的工作量,并提供了相关的提示信息,使开发者能够更加准确和快速地编写代码。同时,它也能提供一定的代码规范性,减少因为拼写错误或者参数错误而引发的运行错误。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值