『原创』让.Net CF实现智能提示(AutoComplete)功能

前言

最近,一直在做Winform方面的开发,有一个公交信息查询的场景,用户在起始站输入框输入部分站点名称,系统能够自动给他建议和提示,类似Google中的自动补全、智能提示之类的功能,在Winform或者WebForm下,.Net都提供了不错的解决方案,甚至可以直接用Ajax中的AutoComplete控件。

但是,问题来了,这个功能要移植到WM平台,我们平常在使用WM手机都可以知道,输入是一件比较麻烦的事情,总是喜欢点点、滑滑、拖拖……反正就是不喜欢输入吧……平常查公交站点,在谷歌里面,都是输入几个关键字就能“被”补全,也许,我有时候都不记得站点的全名了>_<|||。

本想直接用Combox的,发现其没有自动补全功能,谷歌百度一把,发现没有太好的“轮子”,于是,我只有自己造一个带自动补全功能的Combox了。

正文

虽然没有正式的去研究过AutoComplete这个功能,不过,自己想想,也能山寨一个吧。我的思路如下:

  1. 先把站点列表填充好,等待用户输入的关键词
  2. 用户输入关键词,每输入一个字,进行站点列表遍历,查找符合条件的站点,并把它们加入“候补列表”
  3. 用户可以通过Combox的下拉按钮展开Items,查看系统给出的“建议”站点
  4. 用户修改关键词,系统重新比对、填充“候补列表”
  5. 用户关键词越详细,候补列表越精确

有了思路,好像还不错,于是就开始Coding吧。和所有WM项目一样,在设计界面,拖放一个Combox控件到窗体内,并设置Combox的Dock为Top。就这么简单吧。当然,在这里,我们还是一切从简,我没有把站点数据库加载到程序中(实际上,客户下载了程序后,自带了一个SQLite数据库存储站点信息),各位看了我的代码,估计基本能够理解了吧。

定义两个泛型变量,用于存储List信息:

 

代码
1 /// <summary>
2 /// 这个List用于存放站点列表,实际中
3 /// 站点可能是字符串类型也可能是整型,视具体情况而定
4 /// </summary>
5   private List<string> liStops;
6 /// <summary>
7 /// 这个List用于存放候选的站点,也即自动补全的建议项
8 /// 类似于google的候选项目
9 /// </summary>
10   private List<string> liSuggest;

 

 

关键的AutoComplete代码(个人感觉山寨到不行……cbInput为Combox控件):

AutoComplete代码
1 /// <summary>
2 /// 此方法用于自动补全Combox的Items,让Items的项目和用户输入的
3 /// 关键字相匹配
4 /// </summary>
5 /// <param name="text">用户输入的关键字/词</param>
6   private void FillListBox(string text)
7 {
8
9 foreach (string item in liStops)
10 {
11 if (item.IndexOf(text) > -1)//如果该站点包含关键词,则往候补Items中添加这个站点
12   {
13 liSuggest.Add(item);
14 }
15 }
16
17 foreach (object obj in liSuggest)//把候补List中的项目填充到Combox中,让用户感觉是Combox自动完成填补
18   {
19 cbInput.Items.Add(obj.ToString());
20 }
21 }

 

然后,为Combox的KeyUp事件添加如下代码:

 

代码
1 private void cbInput_KeyUp(object sender, KeyEventArgs e)
2 {
3 liSuggest = new List<string>();
4 liSuggest.Clear();//清空上一次的候补项目
5  
6 cbInput.Items.Clear();
7 string text = null;
8 switch (e.KeyCode)//获取本次用户按下的按钮code
9   {
10 case Keys.Left:
11 case Keys.Up:
12 case Keys.Right:
13 case Keys.Down:
14 case Keys.Delete:
15 return;
16 default:
17 text = cbInput.Text.Trim();
18 FillListBox(text);
19 break;
20 }
21 }

 

注意,为了简化操作,我的站点列表在Form_Load事件中进行填充:

 

Form_Load代码
1 private void Form1_Load(object sender, System.EventArgs e)
2 {
3 liStops = new List<string>();
4 for (int i = 0; i < 299; i++)//我定义了窗体Load时,填充站点List,实际中,我们需要选择最佳时机来填充这个List
5   {
6 liStops.Add(i.ToString());
7 }
8 }

 

Ok,至此,一个.Net CF版带AutoComplete功能的、山寨的Combox就实现了。效果如下,感觉还不错……

 

好了,演示结束,实际上,使用中发现,站点列表用什么方式、怎么放到Combox的Items中是一个很有意思的问题,它会影响到用户体验,比如动态加载的时候会有明显延时,都待大家讨论了哦……Jack就暂时先写到这里吧。

最后,推荐一篇老赵的文章《泛型真的会降低性能吗?》 虽然有点年头,不过,很值得一品!

也许,你也应该到这里看看dalelane朋友的这篇文章,也许,这就是正牌的AutoComplete了吧:http://dalelane.co.uk/blog/?p=166

作者:Jack Fan初学博闻 of .NET CF/.Net
出处:http://longqi293.cnblogs.com
本博文欢迎大家浏览和转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,在『参考』的文章中,我会表明参考的文章来源,尊重他人版权。若您发现我侵犯了您的版权,请及时与我联系。
更多文章请看 [置顶]索引贴——移动开发(不断更新中)

知识共享许可协议
本篇博文 by Jack Fan is licensed under a Creative Commons 署名-非商业性使用-相同方式共享 2.5 中国大陆 License.
posted @ 2010-09-15 20:12 鸭梨山大同志 阅读(2187) 评论(13) 编辑 收藏

 回复 引用 查看   
#1楼 2010-09-15 21:04 AppleSeeker(冯峰)      
如果要实现中文字符怎么办呢?比如输入拼音就能自动出现中文。

LIST其实性能很不好,一般autocomplete都至少采用链表存储,这样对于性能消耗最少。

 回复 引用 查看   
#2楼[楼主] 2010-09-15 21:16 Jack Fan      
@AppleSeeker(冯峰)
拼音到中文这个估计还得从.Net平台的解决方案移植吧,还真没接触过哦。
不过List性能真的很不好吗?

 回复 引用 查看   
#3楼 2010-09-15 22:13 爱的angell      
up
 回复 引用 查看   
#4楼[楼主] 2010-09-16 08:40 Jack Fan      
@爱的angell
大哥,终于看到你过来留下脚印了~~~呵呵。

 回复 引用 查看   
#5楼[楼主] 2010-09-16 08:44 Jack Fan      
@AppleSeeker(冯峰)
正在研究链表存储,谢谢~~嘿嘿

这个文章好,推荐+1,收藏。
 回复 引用 查看   
#7楼[楼主] 2010-09-16 08:49 Jack Fan      
@吉日嘎拉 不仅权限管理
:)

 回复 引用 查看   
#8楼 2010-09-16 08:57 施炯      
自带的SHSetInputContext函数好像也可以实现。
 回复 引用 查看   
#9楼[楼主] 2010-09-16 09:22 Jack Fan      
@施炯
恩?!我去看看……哈,想不到。

 回复 引用 查看   
#10楼 2010-09-16 10:47 LRD      
一般的补全都会自动的显示下拉列表,这个Combox好像必须是点击以后才可以显示吧?这样用户每输入一个字符,都需要点击一下才能看到补全的内容(或者是否有补全),用户体验会大打折扣吧。我只是猜测,没有实际运行过你的程序。
 回复 引用 查看   
#11楼[楼主] 2010-09-16 11:04 Jack Fan      
@LRD
Bingo,现在正如你所说,正在找办法。

 回复 引用 查看   
#12楼[楼主] 2010-09-16 15:38 Jack Fan      
@AppleSeeker(冯峰)
Hi,经过查阅,发现LinkedList<>和List<>的区别,发现光光List只是“列表”,而链表和它的区别还是很大的。
具体的性能信息,有待我的进一步测试,你的评论很有帮助,再次感谢~~~嘿嘿~

 回复 引用 查看   
#13楼 2010-09-16 17:21 AppleSeeker(冯峰)      
@Jack Fan
你回答的很好很强大。。。。。