抽点时间写了一个自定义空间,功能是这样的,实现省份,城市的级联更新.数据源是数据库,设计思路是这样的,利用prototype1.5 提供的AJAX功能实现控件级联无刷新功能,请求一个Httphandler,读取数据.
控件呈现:
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 Ucar.Common; using System.Data; using Ucar.Components.Caching; namespace BitAuto.Ucar.CarSelectSortData ... { [DefaultProperty( " Text " )] [ToolboxData( " <{0}:CitySelect runat=server></{0}:CitySelect> " )] public class CitySelect : WebControl, INamingContainer, IPostBackDataHandler ... { private string _validationExpression = @" ^[1-9]d*$ " ; /**/ /// <summary> /// 控件集合 /// </summary> private Label lblProvince = new Label(); private DropDownList dropProvince = new DropDownList(); private Label lblCity = new Label(); private DropDownList dropCity = new DropDownList(); private RegularExpressionValidator valeCityValue = new RegularExpressionValidator(); //控件属性 #region // 控件属性 /**/ /// <summary> /// 城市ID /// </summary> [Bindable( true )] [Category( " Value " )] [DefaultValue( " 0 " )] [Localizable( true )] [Description( " Value " )] public string Value ... { get ... { if ( this .CityId == 0 || this .CityId == - 1 ) ... { return string .Empty; } return ConvertHelper.GetString( this .CityId); } set ... { ViewState[ " Value " ] = value; } } /**/ /// <summary> /// 省份ID /// </summary> [Bindable( true )] [Category( " 省份ID " )] [DefaultValue( " 0 " )] [Localizable( true )] [Description( " 省份ID " )] public int ProvinceId ... { get ... { return ConvertHelper.GetInteger(ViewState[ " ProvinceId " ]); } set ... { ViewState[ " ProvinceId " ] = value; } } /**/ /// <summary> /// 城市ID /// </summary> [Bindable( true )] [Category( " 城市ID " )] [DefaultValue( " 0 " )] [Localizable( true )] [Description( " 城市ID " )] public int CityId ... { get ... { return ConvertHelper.GetInteger(ViewState[ " CityId " ]); } set ... { ViewState[ " CityId " ] = value; } } /**/ /// <summary> /// 布局方式 /// </summary> [Bindable( true )] [Category( " 布局方式 " )] [DefaultValue( " Horizontal " )] [Localizable( true )] [Description( " 布局方式 " )] public RepeatDriections RepeatDriection ... { get ... { if (ViewState[ " RepeatDriection " ] == null ) ... { return RepeatDriections.Horizontal; } return (RepeatDriections)ViewState[ " RepeatDriection " ]; } set ... { ViewState[ " RepeatDriection " ] = value; } } /**/ /// <summary> /// 省份样式 /// </summary> [Bindable( true )] [Category( " 省份样式 " )] [DefaultValue( "" )] [Localizable( true )] [Description( " 省份样式 " )] public string ProvinceCssClass ... { get ... { return ConvertHelper.GetString(ViewState[ " ProvinceCssClass " ]); } set ... { ViewState[ " ProvinceCssClass " ] = value; } } /**/ /// <summary> /// 城市样式 /// </summary> [Bindable( true )] [Category( " 城市样式 " )] [DefaultValue( "" )] [Localizable( true )] [Description( " 城市样式 " )] public string CityCssClass ... { get ... { return ConvertHelper.GetString(ViewState[ " CityCssClass " ]); } set ... { ViewState[ " CityCssClass " ] = value; } } /**/ /// <summary> /// 标签是否可见 /// </summary> [Bindable( true )] [Category( " 标签是否可见 " )] [DefaultValue( " True " )] [Localizable( true )] [Description( " 标签是否可见 " )] public bool LableVisible ... { get ... { if (ViewState[ " LableVisible " ] == null ) ... { return true ; } return ConvertHelper.GetBoolean(ViewState[ " LableVisible " ]); } set ... { ViewState[ " LableVisible " ] = value; } } [Category(" 是否启用非空验证 " )] [DefaultValue( false )] [Description( " 是否启用非空验证 " )] public bool EnabledRequiredFieldValidator ... { get ... { return ConvertHelper.GetBoolean(ViewState[ " EnabledRequiredFieldValidator " ]); } set ... { ViewState[ " EnabledRequiredFieldValidator " ] = value; } } [Category(" 验证提示信息 " )] [DefaultValue( " 请选择城市! " )] [Description( " 验证提示信息 " )] public string ErrorMessage ... { get ... { return ConvertHelper.GetString(ViewState[ " ErrorMessage " ]); } set ... { ViewState[ " ErrorMessage " ] = value; } } [Category(" 验证分组 " )] [DefaultValue( "" )] [Description( " 验证分组 " )] public string ValidationGroup ... { get ... { return ConvertHelper.GetString(ViewState[ " ValidationGroup " ]); } set ... { ViewState[ " ValidationGroup " ] = value; } } #endregion protected override void RenderContents(HtmlTextWriter output) ... { if ( this .Page != null ) ... { this .Page.VerifyRenderingInServerForm( this ); } output.AddAttribute(HtmlTextWriterAttribute.Type, " hidden " ); output.AddAttribute(HtmlTextWriterAttribute.Name, this .UniqueID + " _hdProvinceId " ); output.AddAttribute(HtmlTextWriterAttribute.Id, this .UniqueID + " _hdProvinceId " ); output.AddAttribute(HtmlTextWriterAttribute.Value, this .ProvinceId.ToString()); output.RenderBeginTag(HtmlTextWriterTag.Input); output.RenderEndTag(); output.AddAttribute(HtmlTextWriterAttribute.Type, " hidden " ); output.AddAttribute(HtmlTextWriterAttribute.Name, this .UniqueID); output.AddAttribute(HtmlTextWriterAttribute.Id, this .UniqueID + " _hdCityId " ); output.AddAttribute(HtmlTextWriterAttribute.Value, this .CityId.ToString()); output.RenderBeginTag(HtmlTextWriterTag.Input); output.RenderEndTag(); if (RepeatDriection == RepeatDriections.Vertical) ... { output.RenderBeginTag(HtmlTextWriterTag.Div); output.Write( " <DIV class=' " + this .ProvinceCssClass + " ' > " ); lblProvince.RenderControl(output); output.Write( " " ); dropProvince.RenderControl(output); output.Write( " </DIV> " ); output.Write( " <DIV class=' " + this .CityCssClass + " ' > " ); lblCity.RenderControl(output); output.Write( " " ); dropCity.RenderControl(output); output.Write( " </DIV> " ); } else ... { output.RenderBeginTag(HtmlTextWriterTag.Div); lblProvince.RenderControl(output); output.Write( " " ); dropProvince.RenderControl(output); output.Write( " " ); lblCity.RenderControl(output); output.Write( " " ); dropCity.RenderControl(output); } valeCityValue.RenderControl(output); } protected override void CreateChildControls() ... { // 省份标签 lblProvince.Text = " 省份 " ; lblProvince.ID = " lblCarProducer " ; lblProvince.Visible = LableVisible; this .Controls.Add(lblProvince); dropProvince.ID = " dropProvince " ; this .Controls.Add(dropProvince); // 城市 lblCity.Text = " 城市 " ; lblCity.ID = " lblCarBrand " ; lblCity.Visible = LableVisible; this .Controls.Add(lblCity); dropCity.ID = " dropCity " ; this .Controls.Add(dropCity); valeCityValue.ID = " _valeCityValue " ; valeCityValue.ControlToValidate = this .dropCity.ID; valeCityValue.Display = ValidatorDisplay.None; valeCityValue.ErrorMessage = this .ErrorMessage; valeCityValue.ValidationExpression = _validationExpression; valeCityValue.ValidationGroup = this .ValidationGroup; valeCityValue.SetFocusOnError = true ; valeCityValue.Enabled = this .EnabledRequiredFieldValidator; this .Controls.Add(valeCityValue); dropProvince.Attributes.Add( " onchange " , " cityLoad( " + this .dropProvince.ClientID + " , " + this .dropCity.ClientID + " , " + this .UniqueID + " _hdProvinceId " + " , " + this .UniqueID + " _hdCityId " + " ); " ); dropCity.Attributes.Add( " onchange " , " SetCityID( " + this .UniqueID + " _hdCityId " + " , " + this .dropCity.ClientID + " ); " ); } protected override void OnInit(EventArgs e) ... { Page.RegisterRequiresControlState( this ); Page.ClientScript.RegisterClientScriptResource( typeof (CitySelect), " BitAuto.Ucar.CarSelectSortData.prototype1.5.1.js " ); Page.ClientScript.RegisterClientScriptResource( typeof (CitySelect), " BitAuto.Ucar.CarSelectSortData.CityChange.js " ); base .OnInit(e); } protected override void OnPreRender(EventArgs e) ... { InitProvince(); if ( this .CityId != 0 ) ... { this .ProvinceId = City.GetProvinceIdByCityId( this .CityId); } if ( this .ProvinceId != 0 ) ... { dropProvince.SelectedValue = ProvinceId.ToString(); } InitCity(); if (CityId != 0 ) ... { ControlHelper.InitDropDownListByValue(dropCity, CityId.ToString()); // dropCity.SelectedValue = CityId.ToString(); // dropCity.SelectedIndex = dropCity.Items.IndexOf(dropCity.Items.FindByValue(CityId.ToString())); } base .OnPreRender(e); } IPostBackDataHandler 成员 #region IPostBackDataHandler 成员 public bool LoadPostData( string postDataKey, System.Collections.Specialized.NameValueCollection postCollection) ... { string presentValue = this .ProvinceId.ToString(); string postedValue = postCollection[ this .UniqueID]; string postedProvinceValue = postCollection[ this .UniqueID + " _hdProvinceId " ]; if (presentValue == null || ! presentValue.Equals(postedValue)) ... { this .CityId = ConvertHelper.GetInteger(postedValue); this .ProvinceId = ConvertHelper.GetInteger(postedProvinceValue); return true ; } return false ; } public void RaisePostDataChangedEvent() ... { } #endregion //绑定方法 #region // 绑定方法 protected void InitProvince() ... { dropProvince.Items.Clear(); DataView dv = City.GetProvinceCache(); dv.RowFilter = " pvc_Id<>0 " ; dropProvince.DataTextField = " pvc_Name " ; dropProvince.DataValueField = " pvc_Id " ; dropProvince.DataSource = dv; dropProvince.DataBind(); dropProvince.Items.Insert( 0 , new ListItem( " 请选择省份 " , "" )); } protected void InitCity() ... { dropCity.Items.Clear(); DataView dvCity = City.GetCityCache(); if ( this .ProvinceId != 0 ) ... { dvCity.RowFilter = " pvc_Id= " + dropProvince.SelectedValue; dropCity.DataTextField = " city_Name " ; dropCity.DataValueField = " city_Id " ; dropCity.DataSource = dvCity; dropCity.DataBind(); } dropCity.Items.Insert(0 , new ListItem( " 请选择城市 " , " 0 " )); } #endregion /**/ /// <summary> /// 布局方式 /// </summary> public enum RepeatDriections ... { Vertical, // 垂直 Horizontal // 水平 } } }
Handler实现:
using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Web; using Ucar.Common; using Ucar.Components.Caching; namespace BitAuto.Ucar.CarSelectSortData ... { public class CityHandler : IHttpHandler ... { IHttpHandler 成员 #region IHttpHandler 成员 public bool IsReusable ... { get ... { throw new Exception( " The method or operation is not implemented. " ); } } public void ProcessRequest(HttpContext context) ... { OutputCity(context); } #endregion /**/ /// <summary> /// 输出 /// </summary> protected void OutputCity(HttpContext context) ... { string ProvinceIdStr = context.Request[ " ProvinceId " ]; if ( ! string .IsNullOrEmpty(ProvinceIdStr)) ... { DataView dvCity = City.GetCityCacheByProvinceId(ProvinceIdStr); StringBuilder sb = new StringBuilder(); int i = 0 ; for (i = 0 ; i < dvCity.Table.Rows.Count; i ++ ) ... { sb.Append(dvCity.Table.Rows[i][ " city_Name " ] + " , " + dvCity.Table.Rows[i][ " city_Id " ] + " , " ); } context.Response.Write(sb.ToString().TrimEnd(' , ' )); } } } }
JS:
function cityLoad(dropProvinceid,dropCityid,hdProvinceId,hdCityId) ... { var father = $F(dropProvinceid); $(hdProvinceId).value = father; $(hdCityId).value = '' ; if (father != 0 ) ... { var url = " ~/AjaxCity.aspx " ; var pars = " provinceID= " + father; var myAjax = new Ajax.Request(url, ... {method: ' get ' , parameters: pars, onComplete: function (originalRequest) ... {showResponse(originalRequest,dropCityid)} } ); } else ... { var sel = $(dropCityid); sel.update( "" ); CreatOptions(sel, " 请选择城市 " , "" ); } } function SetCityID(hdCityId,dropCity) ... { $(hdCityId).value = $F(dropCity); } function showResponse(result,dropCityid) ... { var sel = $(dropCityid); var val = result.responseText.split( ' , ' ); sel.update( "" ); CreatOptions(sel, " 请选择城市 " , "" ); for (i = 0 ;i < val.length;i ++ ) ... { text = val[i]; value = val[ ++ i]; CreatOptions(sel,text,value); } } function CreatOptions(colls,text,value) ... { colls.options.add( new Option(text,value)); }
在使用的时候配下hander和连接字符串.
< httpHandlers > < remove verb ="*" path ="*.asmx" /> < add verb ="*" path ="AjaxCity.aspx" validate ="false" type ="BitAuto.Ucar.CarSelectSortData.CityHandler,BitAuto.Ucar.CarSelectSortData" /> </ httpHandlers >