一、前言

  又临近春节,作为屌丝的我,又要为车票发愁了。记得去年出现了各种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事件,获得用户输入

         /// <summary>
/// 站点文本框 键盘按下松开事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtStation_KeyUp(object sender, KeyEventArgs e)
{
TextBox eObj = sender as TextBox; //事件源对象
txtStation_Name = eObj; //当前事件出发对象
if (eObj.Name == "txtStation_S_Name")
{
txtStation_Value = this.txtStation_S_Value; //保存值的textbox
ltb_Stations = this.lb_Start_Stations; //始发站 展示数据的
}
else
{
//到站 控件
txtStation_Value = this.txtStation_E_Value; //保存值的textbox
ltb_Stations = this.lb_End_Stations; //始发站 展示数据的
}
//上下左右
if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Left)
{
if (ltb_Stations.SelectedIndex > )
ltb_Stations.SelectedIndex--;
}
else if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Right)
{
if (ltb_Stations.SelectedIndex < ltb_Stations.Items.Count - )
ltb_Stations.SelectedIndex++;
}
//回车
else if (e.KeyCode == Keys.Enter)
{
StationInfo info = ltb_Stations.SelectedItem as StationInfo;
txtStation_Name.Text = info.StationName_CN;
txtStation_Value.Text = info.StationValue;
ltb_Stations.Visible = false;
}
else
{ if (txtStation_Name.Text != "")
{
IList<StationInfo> dataSource = StationInfo.GetStations(txtStation_Name.Text.Trim());
if (dataSource.Count > )
{
ltb_Stations.DataSource = dataSource;
ltb_Stations.DisplayMember = "StationName_CN";
ltb_Stations.ValueMember = "StationValue";
ltb_Stations.Visible = true;
}
else
ltb_Stations.Visible = false;
}
else
{
ltb_Stations.Visible = false;
}
}
txtStation_Name.Select(txtStation_Name.Text.Length, ); //光标定位到文本框最后
}

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

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

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

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

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

三、一些第三方控件

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

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

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

WinForm AutoComplete 输入提示、自动补全的更多相关文章

  1. angular-ui-bootstrap typeahead 智能提示 自动补全 获取焦点不触发问题的解决

    项目中有一处使用了angular-ui-bootstrap中的typeahead来实现输入框智能提示语自动化补全的功能,存在一个bug, 即输入文字后,当再次点击文本框,其获取焦点后并不会触发智能提示 ...

  2. 【Eclipse】eclipse自动提示+自动补全

    解决代码的自动提示问题: 1.打开 Eclipse -> Window -> Perferences 2.找到Java 下的 Editor 下的 Content Assist , 右边出现 ...

  3. 【学习】eclipse自动提示+自动补全

    解决代码的自动提示问题: 1.打开 Eclipse -> Window -> Perferences 2.找到Java 下的 Editor 下的 Content Assist , 右边出现 ...

  4. PyCharm编辑HTML文件时输入{%不能自动补全

    在PyCharm编辑HTML文件时输入Django模板语言时,发现录入 {% 不能自动补全. 找了一下,发现 setting 里可以设置 Python Template Languages,选择自己使 ...

  5. Codeblock代码提示自动补全(包括结构体成员)

    转:https://blog.csdn.net/haibin8473/article/details/79113650

  6. jQuery搜索框自动补全功能插件实现-autocomplete.js

    最近用nodeclub实现股票的输入关键字自动补全股票信息进行搜索功能,原先用jQuery-ui,结果jQuery-ui库太大,所以考虑用其他插件,最终选择使用autocomplete.js,控件简单 ...

  7. vim下使用YouCompleteMe实现代码提示、补全以及跳转设置

    配置YouCompleteMe 1. 安装vundle vundle是一个管理vim插件的工具,使用vundle安装YouCompleteMe比较方便. 按照作者在https://github.com ...

  8. Vim使用YouCompleteMe达到类似IDE的代码提示、补全,以及其他实用设置

    接触Linux有两年了,vim还是只会简单的操作.最近实在受不了sublime的代码提示,决定花点时间来配置下vim.本文讲自己认为方便的vim配置,称不上完美,只讲究简单实用. 使用 ctags 主 ...

  9. vim自动补全

    Vim 中使用 OmniComplete 为 C/C++ 自动补全 OmniComplete 并不是插件的名字,而是 Vim 众多补全方式中的一种(全能补全).说白了 OmniComplete 其实就 ...

随机推荐

  1. 第二章 rabbitmq在mac上的安装

    下载页: http://www.rabbitmq.com/install-standalone-mac.html 1.下载页面首部的文件(页面下载可能比较慢,使用迅雷下载就好),之后解压到一个合适的路 ...

  2. phpmailer 参数使用说明

    $AltBody--属性 出自:PHPMailer::$AltBody 文件:class.phpmailer.php 说明:该属性的设置是在邮件正文不支持HTML的备用显示 AddAddress--方 ...

  3. NPOI 导出excel带图片,可控大小

    using NPOI.HSSF.UserModel;using NPOI.HSSF.Util;using NPOI.DDF;using NPOI.SS.UserModel;using System.I ...

  4. 使用Spring.net中对Ado.net的抽象封装来访问数据库

    使用Spring.net中对Ado.net的抽象封装来访问数据库     Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入 ...

  5. Android强制弹出,隐藏输入法.

    当我们弹出一个Dialog时候,如果这个Dialog需要输入数据,然后确定后又需要关闭输入法,一般系统的hide,跟show方法总会有各种问题,最霸道的解决方法就是写一个定时器,定时弹出或者关闭输入法 ...

  6. Python解析器源码加密系列之(一):标准c的tmpfile()、tmpfile_s()生成的临时文件究竟放在哪里了?

    这两天由于修改python解释器的需求,需要用到tmpfile()来生成临时文件的FILE*,但是又担心这个临时文件是否存在于磁盘的某个地方,终究会被人找到,所以就简单做了以下几点实验,看看是否可以找 ...

  7. 20135220谈愈敏Linux Book_3

    第3章 进程管理 进程是Unix操作系统抽象概念中最基本的一种,进程管理是操作系统的心脏所在. 3.1 进程 进程:处于执行期的程序以及相关的资源的总称. 线程:在进程中活动的对象,拥有独立的程序计数 ...

  8. JSONProxy - 获取跨域json数据工具

    JSONProxy是一款很好的获取json数据的代理网站,“Enables cross-domain requests to any JSON API”.当你苦于无法跨域获取json数据时,不妨一试, ...

  9. [BZOJ2753][SCOI2012]滑雪与时间胶囊(特殊的有向树形图)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2753 分析: 第一问:直接BFS扩展知道无法扩展 第二问: 看似就是最小树形图啊= = ...

  10. cryptDB安装分析

    cryptDB的安装脚步是用ruby语言写的,由于这里对ruby语言不熟悉,只能做简答的分析.我们先看看cryptDB的目录结构. 主要的目录有bins.doc.main.udf目录,下面我们通过分析 ...