具有Ajax自动建议功能的TextBox控件(附源码)

近期准备翻译一系列Ajax、Javascript方面相关的Web开发文章,以强化专业学习和提升英语读写能力,欢迎大家拍砖挑错,不甚感激!

    原文链接:http://codeproject.com/KB/ajax/AJAXAutoSuggest.aspx  版权归Cassio Alves所有

  源码下载

example.jpg

引言

这是我前段时间制作的具有Ajax 自动建议功能的asp.net文本框控件,它基于Anthem.NET)控件库制作的。

背景

   当我们在开发企业级Web项目时候,我们经常需要让用户从一大堆目录列表中选择其中一项,比如:在一个订单窗体上,用户必须能从众多客户中选择一位。出于性能的考虑,加载一个含50000项的DropDownList控件肯定会让人发疯的。还有一种可采取方法就是打开一个新的窗体供用户查找和选择所需客户。以前我曾尝试过这种方式,但是用户常常发现它非常麻烦,迫切需要一个更好的解决办法。

方案

 Ajax技术的迅速发展使得这个问题变得非常容易解决。自动建议功能的文本框会完全满足这一要求,用户输入所需客户姓名的一部分内容,该控件会自动调整显示匹配的部分。然而,我还没有发现这样的服务器控件能完全满足我的要求,我需要自动建议的文本框服务器控件具有如下特点:

l         内置有效性验证功能

l         基于模板来提供内容

l         能够绑定各种数据源(集合、数据表等)

l         能有DropDownList控件效果

l         Anthem.net平滑集成

l         能显示题头

l         无需调用webservices服务

控件

   该个性化的控件基于Anthem库创建而成。我决定采用Anthem框架,是因为最近我一直在项目中使用它。Atlas目前还不够成熟,与Anthem相比,后者更容易上手、功能更强大。Anthem库有了官方的AutoSuggest控件,但是我还没有正式使用,如果你还不熟悉Anthem.NET框架,我鼓励你体验一下,它非常简洁但效果很好。它的JavaScriptOO模型基于另一个免费AutoSuggest控件而创建的,你可以访问该站点了解该控件,我发现它非常优雅,但是没有我需要的某些功能。

安装

   你只需要在项目中添加Anthem.dllAnthem.AutoSuggest.dll引用,就可以正常使用了,提供下载的文件包含了DLLAutoSuggest控件的源代码和示例项目的源代码。

示例代码

   你所要做的第一件事就是把该控件添加到aspx页面,可以通过拖拉可视化控件的方式,也可以在aspx源文件中直接写标签代码。我没有添加相关的设计视图支持,就是因为我认为你能够忍耐aspx源码 :)。在该例中,我们使用AutoSuggest控件来显示各种各样的名称,用户从中选择一个他最偏爱的。

1 <Anthem:AutoSuggestBox runat="server" 
2     ID="asbFavoriteBand" DataKeyField="ID" 
3     TextBoxDisplayField="Name" AutoCallBack="true" 
4     ItemNotFoundMessage="Item not found!" >
5     <itemtemplate>
6         <%# ((Band)Container.DataItem).Name %>
7     </ItemTemplate>
8 </Anthem:AutoSuggestBox>
9 

我认为绝大部分属性名的含义都一目了然,建议你熟悉所有属性并熟练使用它们,对那些不熟悉Anthem.NET框架的人来说,AutoCallBack属性表示所选内容发生改变之后,AutoSuggest控件将向服务器触发一次回调,它等同于普通ASP.net控件中的AutoPostBack属性,你还可以象在Repeater,DataList DataGrid中一样使用ItemTemplateDataKeyField属性表示控件用来设置SelectedValue属性的键字段。

完成第一步之后,开始处理相应事件。最重要的处理事件是TextChanged,它完成建议列表的填充。另一个重要的事件是SelectValueChanged,在你改变当前值的时候触发该事件,为了封装处理这些操作,需要在OnInit方法中完成下面的代码:

 1 protected override void OnInit(EventArgs e)
 2 {
 3     base.OnInit(e);
 4     this.asbFavoriteBand.TextChanged += 
 5         new Anthem.AutoSuggestBox.TextChangedEventHandler(
 6         asbFavoriteBand_TextChanged);
 7 
 8     this.asbFavoriteBand.SelectedValueChanged += 
 9         new Anthem.AutoSuggestBox.SelectedValueChangedHandler(
10         asbFavoriteBand_SelectedValueChanged);
11 }
12 

下面是处理TextChanged事件的代码:

 1 void asbFavoriteBand_TextChanged(object source, 
 2         Anthem.AutoSuggestEventArgs e)
 3 {
 4     //Creates a dataview from a datatable
 5 
 6     DataView dv = new DataView(_dtBands);
 7 
 8     //Filters the datatable based on the CurrentText property
 9 
10     dv.RowFilter = string.Format("BandName LIKE '%{0}%'", e.CurrentText);
11 
12     //Sets the dataview as the control's datasource
13 
14     asbFavoriteBand.DataSource = dv;
15     asbFavoriteBand.DataBind();
16 }
17 

 在上面的代码片断中,你可以在AutoSuggest控件中用任一数据源。通常是查询数据库获得结果集,通过调用DataBind方法才能将建议列表显示在屏幕上。
值得关注的地方
无可置疑,这个控件要求我们对.NET控件的工作原理有更进一步的理解,如:使用嵌入式web资源(图像、javascriptcss文件),支持基于模板式提供内容,事件触发和处理javascript集成。
面向对象的javascript也值得一看,它的确使处理事情变得更容易。

源码下载
posted @ 2007-12-16 11:57 Kevin Li 阅读(2407) 评论(14)  编辑 收藏 所属分类: 外文翻译

  回复  引用  查看    
#1楼 2007-12-16 17:38 | 高海东      
很好 性能怎么样呢
  回复  引用  查看    
#2楼 2007-12-16 18:02 | 帝之晓      
asp.net ajax toolkit里面的autocomplete控件能够很简单的实现这个功能
  回复  引用  查看    
#3楼 2007-12-16 18:10 | Q.Lee.lulu      
这主题看起来真吃力
  回复  引用  查看    
#4楼 [楼主]2007-12-16 18:28 | finesite      
@高海东
性能还没有怎么关注,测试一下再把报告发上来
@Q.Lee.lulu
呵呵,节约国家电资源啊!这多少也反映我近段时间的心情 :(
  回复  引用    
#5楼 2007-12-16 20:05 | rongj [未注册用户]
这个控件是专门的athem.net控件。
他的源代码在ie6下有bug。需要修改。
性能我测试过,很不错。
  回复  引用    
#6楼 2007-12-17 13:15 | 康冉冉 [未注册用户]
看起来不错。不过这个颜色搭配的,看起来很不舒服。建议修改个看起来舒服的
  回复  引用    
#7楼 2007-12-17 15:26 | 李和平 [未注册用户]
您好!
我尝试着用了下,还不错,只不过在实际的应用中,匹配的记录多点的话,DIV会把页面撑得很大,这点可以不可以用一个层来处理啊,让匹配的下拉条覆盖下面的而不是撑开页面把页面拉得很长
  回复  引用    
#8楼 2007-12-19 13:18 | 李和平 [未注册用户]
继续顶下
  回复  引用  查看    
#9楼 [楼主]2007-12-21 22:14 | finesite      
@李和平
sorry,js知识我最近也再恶补,暂时不能帮助你,看看下面有没有朋友能帮上你?
  回复  引用    
#10楼 2008-01-10 16:17 | 李和平 [未注册用户]
我再来顶下!
  回复  引用    
#11楼 2008-01-10 16:32 | 李和平 [未注册用户]
这个要作成层来显示,不让拉大页面,不太会,不过也可以改进,AutoSuggestBox.js 里
function HideMenuDiv()
{
//this.GetMenuDiv().style.visibility = 'hidden';
this.GetMenuDiv().style.display = 'none';
this.mnSelMenuItem=0;
}
this.GetMenuDiv().style.visibility = 'hidden';在鼠标移开后,撑的页面不会复原,换成this.GetMenuDiv().style.display = 'none';
并且要在function OnKeyUp(evt){}里加上 this.GetMenuDiv().style.display = ''; //显示DIV
不然再次搜索是不会显示结果,另外function OnKeyDown(evt){}里的
HideMenuDiv()方法注释掉,按键的keydown和keyup是互斥的,这样的话enter键就不起作用了,也只能只样了
按上面的处理后 在选中某一项后,页面会再次复原,鼠标移开也同样会复原,情况稍微好点
当然最好的方法是 AutoSuggestBox.js 不作修改,以层的形式弹出来:)




  回复  引用    
#12楼 2008-01-10 16:33 | 李和平 [未注册用户]
顶~~~~~~~~~~~~~~~~~~~~~~~~~
  回复  引用    
#13楼 2008-01-10 22:26 | 李和平 [未注册用户]
重新修改下几个地方,enter键也可以正确响应了
function HideMenuDiv()
{
//this.GetMenuDiv().style.visibility = 'hidden';
this.GetMenuDiv().style.display = 'none';
this.mnSelMenuItem=0;
}

function OnKeyUp(evt)
{
var nKey;
nKey=this.GetKey(evt);

if(nKey == 13)
{
return;
}
this.GetMenuDiv().style.display = ''; //显示DIV

//Skip up/down/enter
if ((nKey!=38) && (nKey!=40) && (nKey!=13))
{......}......
}


function OnKeyDown(evt)
{

this.mbHasFocus=true;

this.msOldTextBoxValue=this.GetTextBoxValue();


var nKey;
nKey=this.GetKey(evt);

//TRACE("OnKeyDown : Key is " + nKey);

//Detect if the user is using the down button
if(nKey==38) //Up arrow
{
this.MoveDown()
}
else if(nKey==40) //Down arrow
{
this.MoveUp()
}
else if(nKey==13) //Enter
{

if (this.IsVisibleMenuDiv())
{
this.HideMenuDiv();
evt.cancelBubble = true;

if (evt.returnValue) evt.returnValue = false;
if (evt.stopPropagation) evt.stopPropagation();

this.mbCancelSubmit=true;
}
else
{
this.mbCancelSubmit=false;
}
}
else
{
return true; //替换了this.HideMenuDiv();避免

}


}
  回复  引用    
#14楼 2008-01-10 22:28 | 李和平 [未注册用户]
return true; //替换了this.HideMenuDiv();不需要再次隐藏

function OnMouseClick(nMenuIndex)
{
this.mnSelMenuItem=nMenuIndex;
this.SetTextBoxValue();
this.HideMenuDiv();
}

象这样又调整了下就好很多了


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-02-17 12:03 编辑过


相关链接: