Atlas学习手记(4):使用AutoComplete Extender实现自动完成功能

摘要:自动完成功能在Ajax时代已经见的很多了,像Google Suggest,很多邮箱中也都有应用。在Atlas对于自动完成功能提供了很好的支持,提供了客户端的AutoComplete Behavior和服务器端的AutoComplete Extender的支持。本文主要看一下使用AutoComplete Extender来实现自动完成功能。

 

主要内容

1AutoComplete Extender介绍

2.一个完整的示例

 

一.AutoComplete Extender介绍

自动完成功能在Ajax时代已经见的很多了,像Google Suggest,很多邮箱中也都有应用,如下图:

Atlas对于自动完成功能提供了很好的支持,提供了客户端的AutoComplete Behavior和服务器端的AutoComplete Extender的支持。本文主要介绍一下使用AutoComplete Extender来实现自动完成功能。一个简单的AutoComplete Extender如下:

<atlas:AutoCompleteExtender runat="server" 

 ID
="autoComplete1">

   
<atlas:AutoCompleteProperties TargetControlID="TextBox1" 

      Enabled
="True" ServicePath="AutoCompleteService.asmx" 

      ServiceMethod
="GetWordList" 

      minimumprefixlength
="1"  />

</atlas:AutoCompleteExtender>

对于AutoComplete Extender来说,它具有如下属性:

属性

描述

ServicePath

指定自动完成功能Web Service的路径

ServicePath="AutoCompleteService.asmx"

ServiceMethod

指定自动完成功能Web Method的名称

ServiceMethod="GetWordList"

DropDownPanelID

指定显示列表的PanelID,一般情况会提供一个默认的,我们无需指定

minimumprefixlength

开始提供自动完成列表的文本框内最少的输入字符数量。

minimumprefixlength="1"

我们需要为AutoComplete Extender控件指定一个AutoCompleteProperties子控件,它同样具有如下属性:

属性

描述

ServicePath

AutoComplete ExtenderServicePath

ServiceMethod

AutoComplete ExtenderServiceMethod

minimumprefixlength

AutoComplete Extenderminimumprefixlength

Enabled

是否开启自动完成功能,默认值为false

Enabled="True"

TargetControlID

指定自动完成功能应用到哪个TextBox上,设置Web服务器TextBox控件的ID

TargetControlID="TextBox1"

下面通过一个例子来看一下具体如何使用,来自于Atlas的官方网站。

二.一个完整的示例

1.准备相关的数据源,这里使用一个本文文件作为我们的数据源,当然你也可以从数据库中读数据,拷贝如下单词为words.txt并保存在App_Data文件夹:

单词库

2.编写Web Service用来提供单词列表,这里我们并不关心具体的实现逻辑,只关心Web Method接收什么样的参数,最后返回一个string数组即可。

using System;

using System.IO;

using System.Web;

using System.Collections;

using System.Collections.Generic;

using System.Threading;

using System.Web.Services;

using System.Web.Services.Protocols;

using System.Xml.Serialization;


/// <summary>

/// Summary description for AutoCompleteService

/// </summary>


[WebService(Namespace 
= "http://tempuri.org/")]

[WebServiceBinding(ConformsTo 
= WsiProfiles.BasicProfile1_1)]

public class AutoCompleteService : System.Web.Services.WebService {

    
public AutoCompleteService () {

        
//Uncomment the following line if using designed components 

        
//InitializeComponent(); 

    }


    
private static string[] autoCompleteWordList = null;

    [WebMethod]

    
public String[] GetWordList(string prefixText, int count)

    
{
        
if (autoCompleteWordList == null)

        
{
            
string[] temp = File.ReadAllLines(Server.MapPath("~/App_Data/words.txt"));

            Array.Sort(temp, 
new CaseInsensitiveComparer());

            autoCompleteWordList 
= temp;
        }


        
int index = Array.BinarySearch(autoCompleteWordList, prefixText,

          
new CaseInsensitiveComparer());

        
if (index < 0)

        
{
            index 
= ~index;
        }


        
int matchingCount;

        
for (matchingCount = 0;

             matchingCount 
< count && index + matchingCount <

             autoCompleteWordList.Length;

             matchingCount
++)

        
{

            
if (!autoCompleteWordList[index +

              matchingCount].StartsWith(prefixText,

              StringComparison.CurrentCultureIgnoreCase))

            
{
                
break;
            }

        }


        String[] returnValue 
= new string[matchingCount];

        
if (matchingCount > 0)

        
{
            Array.Copy(autoCompleteWordList, index, returnValue, 
0,

              matchingCount);
        }


        
return returnValue;
    }

}

3.添加AutoComplete Extender,首先需要添加一个ScriptManager,再添加一个服务器端的控件和一个AutoComplete Extender,并设置相关的参数,代码如下:

<atlas:ScriptManager id="AtlasPage1" runat="server" />

<div class="page"id="links">

 
<div id="content">

   
<h2>AutoComplete server control</h2>

   
<asp:TextBox ID="TextBox1" runat="server" Width="220px"></asp:TextBox>

    
<atlas:AutoCompleteExtender runat="server" 

     ID
="autoComplete1">

       
<atlas:AutoCompleteProperties

          
TargetControlID="TextBox1" 

          Enabled
="True" ServicePath="AutoCompleteService.asmx" 

          ServiceMethod
="GetWordList" 

          minimumprefixlength
="1"  />

    
</atlas:AutoCompleteExtender>     

 
</div>

</div>

好了,到这里整个步骤就全部完成了,运行后就可以看到效果如下:

完整示例下载:http://terrylee.cnblogs.com/Files/Terrylee/AutoCompleteExtenderDemo.rar

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2006-07-27 19:31 TerryLee 阅读(8179) 评论(90)  编辑 收藏 网摘 所属分类: [08]  Web开发[01]  .NET大本营

  回复  引用    
#1楼 2006-07-27 19:58 | oksina [未注册用户]
good.
  回复  引用  查看    
#2楼 2006-07-27 20:53 | 阿一      
<atlas:AutoCompleteProperties

TargetControlID="TextBox1"

Enabled="True" ServicePath="AutoCompleteService.asmx"

ServiceMethod="GetWordList"

minimumprefixlength="1" />
这里只能调用Web服务吗?
ServicePath="AutoCompleteService.asmx"

  回复  引用  查看    
#3楼 2006-07-28 01:31 | Dflying Chen      
@阿一
稍加修改可以调用页面上的Web Method
  回复  引用  查看    
#4楼 [楼主]2006-07-28 08:02 | TerryLee      
@Dflying Chen

多谢啊,这一点我也不知道,呵呵:-)
  回复  引用  查看    
#5楼 2006-07-28 09:34 | aspnetx      
楼主觉得atlas是否会自动集成到asp.net3里头呢?
  回复  引用  查看    
#6楼 [楼主]2006-07-28 09:48 | TerryLee      
@aspnetx

有这个可能性,昨天不是还看了那篇新闻了嘛,只是个人猜测,最终还得看MS
  回复  引用  查看    
#7楼 2006-07-28 13:57 | aspnetx      
再请教一个问题
就是我能否不用atlas网站模板,而是直接创建一个asp.net网站,然后引入Microsoft.Web.Atlas.dll
也就是说正常的一个asp.net(2.0)网站引入这个dll是否就和atlas提供的网站模板一样呢?如果不一样的话会有什么不同,或者能否通过其它的方式把现有的asp.net2.0网站转换成atlas的网站

谢谢
  回复  引用  查看    
#8楼 [楼主]2006-07-28 14:07 | TerryLee      
@aspnetx
引入Microsoft.Web.Atlas.dll这种方式是完全可以的,参见:
http://terrylee.cnblogs.com/archive/2006/07/27/Atlas_UpdatePanel.html

这里引入Atlas_UpdatePannel就是采用了这种方式。
  回复  引用    
#9楼 2006-07-29 22:20 | ywolf123 [未注册用户]
[WebMethod]

public String[] GetWordList(string prefixText, int count)
这个方法有两个参数,可是<atlas:AutoCompleteProperties

TargetControlID="TextBox1"

Enabled="True" ServicePath="AutoCompleteService.asmx"

ServiceMethod="GetWordList"

minimumprefixlength="1" />
这里边的设置里面只是指定了方法名字,却没有指定参数,具体在调用时到底发生了些什么事情呢?
  回复  引用    
#10楼 2006-07-29 22:22 | ywolf123 [未注册用户]
另外,我试验了下把public String[] GetWordList(string prefixText, int count) 修改成public String[] GetWordList(string sdafjk,string prefixText, int count)也就是人为的把GetWordList的参数再加几个也还可以,这就怪了

  回复  引用  查看    
#11楼 [楼主]2006-07-30 10:24 | TerryLee      
@ywolf123

具体需要参考相关的源码了!
  回复  引用    
#12楼 2006-08-04 11:51 | Other_tang@yahoo.com.cn [未注册用户]
我是个Atlas的初学者
敬佩楼主的奉献精神
我把AutoCompleteService做了一些修改,个人觉得更简洁一些
欢迎大家指正

public class AutoCompleteService : System.Web.Services.WebService {

private static string[] autoCompleteWordList = new string[101];

public AutoCompleteService () {
//添加0~100这些数字,这样也可以达到演示的效果,就不需要读取文件了
//在构造函数中初始化autoCompleteWordList,就不需要每次在GetWordList中判断null
for (int i = 0; i <= autoCompleteWordList.Length-1; ++i)
{
autoCompleteWordList[i] = i.ToString();
}
Array.Sort(autoCompleteWordList);
}

[WebMethod]
public string[] GetWordList(string prefixText, int count) {
//算法和楼主一样,写法稍微简化了些
string[] result = null;
int start=-1;
int end=autoCompleteWordList.Length-1;
for (int i = 0; i < autoCompleteWordList.Length; i++)
{
if (autoCompleteWordList[i].StartsWith(prefixText))
{
if (start == -1)
start = i;
}
else
{
if (start != -1)
{
end = i - 1;
break;
}
}
}
if (start != -1)
{
result = new string[end - start + 1];
Array.Copy(autoCompleteWordList, start, result, 0, end - start + 1);
}
return result;
}

}
  回复  引用  查看    
#13楼 [楼主]2006-08-04 12:39 | TerryLee      
@Other_tang@yahoo.com.cn
谢谢,这个算法是Atlas官方网站提供的,这里的逻辑不是我们所关注的重点,在实际应用中,数据一般都是从数据库中读取的,可以参考:
http://www.codeproject.com/useritems/Autocomplete.asp
  回复  引用  查看    
#14楼 2006-08-08 11:23 | SHY520      
@Dflying Chen
怎么才能调用页面上的WebMethod?要修改什么东西?
  回复  引用  查看    
#16楼 2006-08-09 17:07 | SHY520      
@TerryLee
I See ,Thank You!
  回复  引用    
#17楼 2006-08-11 13:03 | Teng_s2000 [未注册用户]
太好了
我发现Atlas方面的研究就
TerryLee 和 Dflying Chen
的好啊
  回复  引用    
#18楼 2006-08-11 14:32 | Teng_s2000 [未注册用户]
To TerryLee

AutoComplete的样式怎么定义呢
如同Google那东西一样,设置颜色...
谢谢
  回复  引用  查看    
#19楼 [楼主]2006-08-14 08:27 | TerryLee      
@Teng_s2000
谢谢,把自己学习的过程记录下来,与大家分享,对别人也是一种帮助!
  回复  引用  查看    
#20楼 [楼主]2006-08-14 08:29 | TerryLee      
@Teng_s2000
在AutoCompleteExtender中似乎没有提供这个功能,试试客户端的AutoComplete Behavior
  回复  引用  查看    
#21楼 2006-08-18 01:55 | Gorster      
多谢TerryLee的好文章,这个东西对中文还是不支持,js的缺陷
  回复  引用  查看    
#22楼 2006-08-19 11:36 | spiderNet      
<atlas:ScriptManager id="AtlasPage1" runat="server" />这句我看到有的时候是分开来写,里面会包含一些内容如WEB service的调用,但有的时候又是以这种单句的型式来写,究竞什么时候要采用分开来写的方式呢?还有就是在分开来写时,里面都可以包含哪些内容呢?(对于FORM、HTML控件、SERVER控件、Atlas控件而言)
  回复  引用  查看    
#23楼 2006-08-23 13:36 | 少个阿虎      
<atlas:AutoCompleteProperties

TargetControlID="TextBox1"

Enabled="True" ServicePath="AutoCompleteService.asmx"

ServiceMethod="GetWordList"

minimumprefixlength="1" />

</atlas:AutoCompleteExtender>

如何指定GetWordList的参数,我看Web service该Web Method会有2个参数!
  回复  引用  查看    
#24楼 [楼主]2006-08-23 13:59 | TerryLee      
@Gorster
不客气
  回复  引用  查看    
#25楼 [楼主]2006-08-23 14:00 | TerryLee      
  回复  引用  查看    
#26楼 [楼主]2006-08-23 14:01 | TerryLee      
@少个阿虎
这两个参数是固定的,不需要手工指定
  回复  引用  查看    
#27楼 2006-08-24 09:46 | 天轰穿      
不能读取中文和数字,我尝试在文本文件中增加中文和数字,都读不出来!

这样一来,这个控件对我写中文的来说,实际上是没有用了!

因为我不能把中国的地名全部E化
  回复  引用  查看    
#28楼 2006-08-24 10:10 | 少个阿虎      
@TerryLee
public String[] GetWordList(string prefixText, int count)
prefixText指我手动输入的字符(根据输入字符给出提示项),count是固定值10吗,能不能通过代码指定这两个参数,如我想列出20个提示项。
  回复  引用  查看    
#29楼 [楼主]2006-08-25 08:39 | TerryLee      
@少个阿虎
count应该不是提示项吧,好像是开始提供自动完成列表的文本框内最少的输入字符数量,通过属性minimumprefixlength指定
  回复  引用    
#30楼 2006-08-25 14:57 | liuhaolghl [未注册用户]
怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???怎么不得行呢???
  回复  引用  查看    
#31楼 [楼主]2006-08-28 08:35 | TerryLee      
@liuhaolghl
什么不行啊?
  回复  引用