• 我的AutoComplete有源码


    AutoComplete这个控件网上已经很多了,以前在一个项目中用过一次,但是没有很好的去封装它。最近在学习控件开发,感觉这个控件以后还会用到,便尝试着写了一个。

    虽然这个控件网上随便一搜就有,但为了能将它融合到自己的框架中,自己开发一个也是有必要的,而且开发的过程,也是学习和提高的契机。

    首先展示一下使用的方法和效果吧

    1.新建一个空白的页面,引入必要的脚本和样式文件(Jquery和自己的脚本库,这个脚本库包含的不仅仅是AuctoComplete这个控件需要用到的脚本),然后拖入或者手写一个AutoComplete控件,本质上它是一个经过扩展的TextBox控件

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <title></title>
    <script type ="text/javascript" src ="http://www.cnblogs.com/js/jquery-1.4.1-vsdoc.js"></script>
    <script type ="text/javascript" src ="http://www.cnblogs.com/js/Core.js"></script>
    <link href="http://www.cnblogs.com/style/web.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
    <form id="form1" runat="server">
    <Jiuzh:AutoComplete runat="server" ID ="acExample" ></Jiuzh:AutoComplete>
    </form>
    </body>
    </html>

    2.双击控件,为它增加一个ontextchanged事件函数,同时设置控件的MinStart属性,该属性表示引发查询的最小字符数,另外还有一个用于绑定查询时额外参数的Params属性,这里没有用到。HTML代码和C#代码分别如下

        <form id="form1" runat="server">
    <Jiuzh:AutoComplete runat="server" ID ="acExample" ontextchanged="acExample_TextChanged" MinStart="2" ></Jiuzh:AutoComplete>
    </form>
            protected List<string> acExample_TextChanged(object sender)
    {
    List<string> result = new List<string>();
    result.Add("1213");
    result.Add("1234");
    result.Add("5345");
    result.Add("1241");
    return result.Where(s => s.Contains(acExample.Text)).ToList();
    }


    大功告成,启动该页面,在文本框中输入 12 ,结果如下图所示

    怎么样,使用方式还算简单吧。 

    ========================接下来是万众瞩目的代码解析了==============================

    首先这个控件用到的技术很简单,主要是Jquery的AJAX接口和ASP.NET的控件开发技术。

    我想对于新手来说肯定对于该控件的ontextchanged事件函数很感兴趣,没有AUTOPOSTBACK属性为TRUE,它是怎么触发服务器事件的呢,另外事件的函数签名怎么也变了,只有一个sender 参数。

    首先我们看下页面生成后的HTML代码

    <input onkeyup="AutoComplate(this,2,{})" name="acExample" type="text" id="acExample" />

    看,一个INPUT控件而已,在生成页面时为它绑定了onkeyup事件,onkeyup事件执行了AutoComplate函数,该函数有3个参数,第一个参数不用说,第二个参数就是刚才设置的MinStart参数,第三个参数则是查询时绑定的额外参数.

    接下来看AutoComplate这个函数

     function AutoComplate(obj, len, param) {
    var ctl = $(obj);
    var val = ctl.val();
    var ctlId = ctl.attr("id");
    if (val.length == 0) {
    $("#" + ctlId + "_Auto").hide();
    return;
    }
    if (val.length < len)
    return;
    var div = $("#" + ctlId + "_Auto");
    if (div.length == 0) {
    div = $("<div id=\"" + ctlId + "_Auto\" style =\"position:absolute; display:none; border:1px solid #817f82; background-color:#ffffff; 200px\"></div>");
    $('body').append(div);
    }
    param ["__EVENTTARGET"]=ctlId;
    param[ctlId] = val;
    var wu_nopar = window.location.href.split("?")[0].split("/");
    var pageName = wu_nopar[wu_nopar.length - 1];
    $.post(pageName+"?action=list", param, function (data) {
    var result = eval(data);
    if (result.length > 0) {
    div.html("");
    var table = $("<table style='100%' ><tbody></tbody></table>");
    for (var i = 0; i < result.length; i++) {
    var tr = $("<tr><td >" + result[i] + "</td></tr>");
    tr.mouseover(function () {
    $(this).addClass('JZac');
    });
    tr.mouseout(function () {
    $(this).removeClass('JZac');
    });
    tr.click(function () {
    $(obj).val($(this).children().eq(0).html());
    div.hide();
    });
    table.append(tr);
    }
    div.append(table);
    var of = $(obj).offset();
    var top = of.top + $(obj).height();
    div.css("top", top + 5);
    div.css("left", of.left);
    div.width($(obj).width());
    div.show();
    }
    else
    div.hide();
    });
    }


    对于熟悉Jquery的来说,以上代码没什么好解释的,关键是这两句

         param ["__EVENTTARGET"]=ctlId;
    param[ctlId] = val;

    param参数我刚才解释过是查询时的额外参数,但在这个AutoComplete函数中,我为它额外增加了两个参数,第一个参数名为__EVENTTARGET,值为当前的控件Id,第二个参数为当前的控件Id,值为控件的文本值。有了这两个参数,并且以POST方式提交,在服务器端,我们的AutoComplete控件的ontextchanged事件便触发了。也就是说在AutoComplete函数中,我模拟了触发控件服务器端事件的数据并以AJAX的方式提交。

    最后来看控件的源代码。首先我定义了一个委托用于替代默认的委托

    public delegate List <string > AutoCompleteHandler(object sender);

    接着是控件代码

    [ToolboxData("<{0}:AutoComplete runat=server></{0}:AutoComplete>")]
    public class AutoComplete : TextBox
    {
    public new event AutoCompleteHandler TextChanged;

    private Params _params=new Params ();
    public Params Params
    {
    get
    {
    return _params;
    }
    }

    [TypeConverter (typeof (uint ))]
    public string MinStart { get; set; }

    protected virtual void OnAutoCompleteChanged(EventArgs e)
    {
    if (TextChanged != null)
    {
    List<string> result = TextChanged(this);
    JavaScriptSerializer ser = new JavaScriptSerializer();
    string json = ser.Serialize(result);
    Context.Response.ContentType = "text/plain";
    Context.Response.Write(json);
    Context.Response.End();
    }
    }

    protected override void RaisePostDataChangedEvent()
    {
    OnAutoCompleteChanged(EventArgs.Empty);
    // base.RaisePostDataChangedEvent();
    }

    public override void RenderControl(HtmlTextWriter writer)
    {
    StringBuilder sb=new StringBuilder ();
    for (int i = 0; i < Params.Count; i++)
    {
    sb.AppendFormat("{0}:{1}", Params .Keys [i], Params [i]);
    }
    writer.AddAttribute("onkeyup", "AutoComplate(this,"+MinStart+",{" + sb.ToString () + "})");
    base.RenderControl(writer);
    }


    }



    首先是这句 public new event AutoCompleteHandler TextChanged;例用new关键字使得TextChanged事件执行我之前定义的委托。然后在OnAutoCompleteChanged函数中,取得TextChanged事件返回的结果,同时Response.End();返回数据。

    ============================OVER=========================================

    以上便是该控件的介绍,希望对大家有帮助,有不对的地方还请指出。

    因为有人需要一个完整的代码包,便做了一个DEMO,以下是链接:https://files.cnblogs.com/xxfss2/Demo.rar

  • 相关阅读:
    Linux/Unix中的#!和!#
    包含min函数的栈
    顺时针打印矩阵
    二叉树镜像
    数的子结构
    合并两个排序的链表
    反转链表
    链表中倒数第K个结点
    调整数组顺序使奇数位于偶数前面
    在O(1)时间删除链表结点
  • 原文地址:https://www.cnblogs.com/xxfss2/p/2434155.html
Copyright © 2020-2023  润新知