WEB开发网
开发学院WEB开发ASP.NET ASP.NET: Custom AutoCompleteTextBox WebControl... 阅读

ASP.NET: Custom AutoCompleteTextBox WebControl [With Source Code]

 2006-02-28 17:03:55 来源:WEB开发网   
核心提示:这是一个Teddy最近封装的AutoCompleteTextBox,我们知道,ASP.NET: Custom AutoCompleteTextBox WebControl [With Source Code],asp.net本身的TextBox也是支持一定的AutoComplete功能的,但是那是依赖浏览器实现的,实现

这是一个Teddy最近封装的AutoCompleteTextBox。我们知道,asp.net本身的TextBox也是支持一定的AutoComplete功能的,但是那是依赖浏览器实现的,并不能指定自定义的AutoComplete候选项。本文列举的AutoCompleteTextBox则弥补了这个缺憾。只需设置AutoCompleteTextBox.AutoCompleteData属性,传递一个string[],就能使TextBox支持自定义候选项了。

AutoComplete逻辑

如果没有匹配当前输入的候选项,则同一般的TextBox;
如果只有一个候选项与当前输入匹配,则自动完成;
如果有超过一个候选项与当前输入匹配,则在textbox中自动完成第一个候选项,并弹出包含所有候选项的弹出框。

实现源码

源码是在VS2005编译的,不过实际上几乎没有使用依赖2.0的语法,在vs2003下经极少修改就同样能编译的。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace Ilungasoft.Framework.Web.UI.WebControls
{
   [ToolboxData("<{0}:AutoCompleteTextBox runat=server></{0}:AutoCompleteTextBox>")]
   public class AutoCompleteTextBox : WebControl
   {
     PRivate Members#region Private Members

   private TextBox textBox = new TextBox();
     private HtmlGenericControl autoCompleteFrame = new HtmlGenericControl();

   private string ToJsStringArray(params string[] strs)
     {
       if (strs != null && strs.Length > 0)
       {
         StringBuilder sb = new StringBuilder();
         sb.Append(" new Array(");

       foreach (string str in strs)
         {
           sb.Append(string.Format("'{0}', ", str.Replace("'", "\\'")));
         }

       return sb.ToString().TrimEnd(',', ' ') + ");";
       }
       else
       {
         return " new Array;";
       }
     }

   private string MakeUniqueID(string id)
     {
       if (id != null && id.Trim().Length > 0)
       {
         return string.Concat(this.UniqueID.Replace("$", "_"), "_", id);
       }
       else
       {
         return this.UniqueID.Replace("$", "_");
       }
     }

   #endregion

   Properties#region Properties

   [Bindable(true)]
     [Category("Appearance")]
     [DefaultValue("")]
     [Localizable(true)]
     public string Text
     {
       get
       {
         if (Page.IsPostBack)
         {
           textBox.Text = Page.Request.Form[MakeUniqueID("textBox")];
         }
         return textBox.Text;
       }
       set
       {
         textBox.Text = value;
       }
     }

   [Bindable(true)]
     [Category("Behavior")]
     [DefaultValue("")]
     [Localizable(true)]
     public int MaxLength
     {
       get
       {
         return textBox.MaxLength;
       }
       set
       {
         textBox.MaxLength = value;
       }
     }

   [Bindable(true)]
     [Category("Behavior")]
     [DefaultValue(false)]
     [Localizable(true)]
     public bool ReadOnly
     {
       get
       {
         return textBox.ReadOnly;
       }
       set
       {
         textBox.ReadOnly = value;
       }
     }

   public string[] AutoCompleteData
     {
       get
       {
         string[] s = (string[])ViewState["AutoCompleteData"];
         return ((s == null) ? null : s);
       }
       set
       {
         ViewState["AutoCompleteData"] = value;
       }
     }

   #endregion

   Overriden Members#region Overriden Members

   protected override void CreateChildControls()
     {
       create textBox#region create textBox

     textBox.ID = MakeUniqueID("textBox");
       textBox.AutoCompleteType = AutoCompleteType.Disabled;
       textBox.Attributes.Add("onkeypress", string.Format("return __DoAutoComplete(event, '{0}')", MakeUniqueID(null)));
       textBox.Attributes.Add("onblur", string.Format("if (!document.show_{0}) document.getElementById('{1}').style.display = 'none';", MakeUniqueID(null), MakeUniqueID("autoCompleteFrame")));
       textBox.Width = Width;

     #endregion

     create autoCompleteFrame#region create autoCompleteFrame

     autoCompleteFrame.TagName = "iframe";
       autoCompleteFrame.ID = MakeUniqueID("autoCompleteFrame");
       autoCompleteFrame.Attributes.Add("style", "display:none; position: absolute; border: ridge 1px");
       autoCompleteFrame.Attributes.Add("frameborder", "0");
       autoCompleteFrame.Attributes.Add("marginheight", "0");
       autoCompleteFrame.Attributes.Add("marginwidth", "2");
       autoCompleteFrame.Attributes.Add("scrolling", "auto");
       autoCompleteFrame.Attributes.Add("width", Width.ToString());
       autoCompleteFrame.Attributes.Add("height", "100px");
       autoCompleteFrame.Attributes.Add("src", "javascript:''");
       autoCompleteFrame.Attributes.Add("onmouSEOver", string.Format("document.show_{0} = true;", MakeUniqueID(null)));
       autoCompleteFrame.Attributes.Add("onmouseout", string.Format("document.show_{0} = false;", MakeUniqueID(null)));

     #endregion
     }

   protected override void OnPreRender(EventArgs e)
     {
       Register Client Script Block#region Register Client Script Block

     if (!Page.ClientScript.IsClientScriptBlockRegistered("__DoAutoComplete"))
       {
         string script = string.Concat(
           "<script language=\"Javascript\" type=\"text/javascript\">\r\n",
           "   var isOpera = navigator.userAgent.indexOf('Opera') > -1;\r\n",
           "   var isIE = navigator.userAgent.indexOf('MSIE') > 1 && !isOpera;\r\n",
           "   var isMoz = navigator.userAgent.indexOf('Mozilla/5.') == 0 && !isOpera;\r\n",
           "\r\n",
           "   function textboxSelect (oTextbox, iStart, iEnd)\r\n",
           "   {\r\n",
           "    switch(arguments.length) {\r\n",
           "      case 1:\r\n",
           "        oTextbox.select();\r\n",
           "        break;\r\n",
           "\r\n",
           "      case 2:\r\n",
           "        iEnd = oTextbox.value.length;\r\n",
           "        /* falls through */\r\n",
           "        \r\n",
           "      case 3:      \r\n",
           "        if (isIE) {\r\n",
           "          var oRange = oTextbox.createTextRange();\r\n",
           "          oRange.moveStart(\"character\", iStart);\r\n",
           "          oRange.moveEnd(\"character\", -oTextbox.value.length + iEnd);    \r\n",
           "          oRange.select();                        \r\n",
           "        } else if (isMoz){\r\n",
           "          oTextbox.setSelectionRange(iStart, iEnd);\r\n",
           "        }           \r\n",
           "    }\r\n",
           "\r\n",
           "    oTextbox.focus();\r\n",
           "   }\r\n",
           "\r\n",
           "   function textboxReplaceSelect (oTextbox, sText)\r\n",
           "   {\r\n",
           "    if (isIE) {\r\n",
           "      var oRange = document.selection.createRange();\r\n",
           "      oRange.text = sText;\r\n",
           "      oRange.collapse(true);\r\n",
           "      oRange.select();                 \r\n",
           "    } else if (isMoz) {\r\n",
           "      var iStart = oTextbox.selectionStart;\r\n",
           "      oTextbox.value = oTextbox.value.substring(0, iStart) + sText + oTextbox.value.substring(oTextbox.selectionEnd, oTextbox.value.length);\r\n",
           "      oTextbox.setSelectionRange(iStart + sText.length, iStart + sText.length);\r\n",
           "    }\r\n",
           "\r\n",
           "    oTextbox.focus();\r\n",
           "   }\r\n",
           "\r\n",
           "   function autocompleteMatch (sText, arrValues)\r\n",
           "   {\r\n",
           "    var retMatches = \"\"; \r\n",
           "    \r\n",
           "    for (var i=0; i < arrValues.length; i++)\r\n",
           "    {\r\n",
           "      if (arrValues[i].indexOf(sText) == 0)\r\n",
           "      {\r\n",
           "        retMatches += arrValues[i] + ',';\r\n",
           "      }\r\n",
           "    }\r\n",
           "    \r\n",
           "    if (retMatches.length > 0)\r\n",
           "    {\r\n",
           "      retMatches = retMatches.substr(0, retMatches.length - 1);\r\n",
           "    } \r\n",
           "\r\n",
           "    return retMatches;\r\n",
           "   }\r\n",
           "\r\n",
           "   function __DoAutoComplete(oEvent, id)\r\n",
           "   {\r\n",
           "     var oTextbox = document.getElementById(id + '_textBox');\r\n",
           "     var frame = document.getElementById(id + '_autoCompleteFrame');\r\n",
           "     var arrValues =  document[id + '_data'];\r\n",
           "    \r\n",
           "     switch (oEvent.keyCode) \r\n",
           "     {\r\n",
           "       case 38: //up arrow  \r\n",
           "       case 40: //down arrow\r\n",
           "       case 37: //left arrow\r\n",
           "       case 39: //right arrow\r\n",
           "       case 33: //page up  \r\n",
           "       case 34: //page down  \r\n",
           "       case 36: //home  \r\n",
           "       case 35: //end          \r\n",
           "       case 13: //enter  \r\n",
           "       case 9: //tab  \r\n",
           "       case 27: //esc  \r\n",
           "       case 16: //shift  \r\n",
           "       case 17: //ctrl  \r\n",
           "       case 18: //alt  \r\n",
           "       case 20: //caps lock\r\n",
           "       case 8: //backspace  \r\n",
           "       case 46: //delete\r\n",
           "         return true;\r\n",
           "         break;\r\n",
           "         \r\n",
           "       default:\r\n",
           "         textboxReplaceSelect(oTextbox, String.fromCharCode(isIE ? oEvent.keyCode : oEvent.charCode));\r\n",
           "         var iLen = oTextbox.value.length;\r\n",
           "\r\n",
           "         var sMatches = autocompleteMatch(oTextbox.value, arrValues);\r\n",
           "\r\n",
           "         if (sMatches.length > 0)\r\n",
           "         {\r\n",
           "          var arrMatches = sMatches.split(',');\r\n",
           "          oTextbox.value = arrMatches[0];\r\n",
           "          textboxSelect(oTextbox, iLen, oTextbox.value.length);\r\n",
           "          \r\n",
           "          if (arrMatches.length > 1)\r\n",
           "          {\r\n",
           "             frame.style.display = 'inline';\r\n",
           "             frame.height = '100';\r\n",
           "             \r\n",
           "             frame.contentWindow.document.body.innerHTML = '';\r\n",
           "             for (var i = 0; i < arrMatches.length; i++)\r\n",
           "             {\r\n",
           "               frame.contentWindow.document.body.innerHTML += '<div style=\"width: 100%; cursor: default\" onmouseover=\"this.style.backgroundColor=\\'#316AC5\\'; this.style.color=\\'white\\';\" onmouseout=\"this.style.backgroundColor=\\'\\'; this.style.color=\\'black\\';\" onclick=\"parent.document.getElementById(\\'' + id + '_textBox\\').value = this.innerHTML\">' + arrMatches[i] + '</div>';\r\n",
           "             }\r\n",
           "             \r\n",
           "             frame.contentWindow.document.body.style.backgroundColor = 'white';\r\n",
           "             frame.contentWindow.document.onclick = function() { document.getElementById(id + '_autoCompleteFrame').style.display = 'none'; };\r\n",
           "          }  \r\n",
           "         }  \r\n",
           "         \r\n",
           "         return false;\r\n",
           "     }     \r\n",
           "   }\r\n",
           "</script>\r\n",
           "");
         Page.ClientScript.RegisterClientScriptBlock(typeof(string), "__DoAutoComplete", script);
       }

     if (!Page.ClientScript.IsClientScriptBlockRegistered(MakeUniqueID("data")))
       {
         Page.ClientScript.RegisterClientScriptBlock(typeof(string), MakeUniqueID("data"), string.Format("<script language=\"javascript\" type=\"text/javascript\">document.{0}_data = {1}</script>", MakeUniqueID(null), ToJsStringArray(AutoCompleteData)));
       }

     #endregion
     }

   protected override void RenderContents(HtmlTextWriter output)
     {
       output.WriteLine(string.Format("<div onmouseleave=\"document.getElementById('{0}').style.display = 'none';\" style=\"width:{1}\" >", MakeUniqueID("autoCompleteFrame"), Width));
       textBox.RenderControl(output);
       output.WriteLine("<br />");
       autoCompleteFrame.RenderControl(output);
       output.WriteLine("</div>");
     }

   #endregion
   }
}
下载

http://teddyma.cnblogs.com/Files/teddyma/AutoCompleteTextBox.zip

Tags:ASP NET Custom

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接