刚好手头有需要用到多级联动的功能,平常写一堆代码用于数据绑定、事件绑定,实在太烦琐了,于是想办法简化一下,也顺便练练手~_~
实现比较简单,不多说,具体代码如下:
using System; using System.Web.UI.WebControls; /// <summary> /// 多级联动查询 /// </summary> public class CascadeQuery { ListControl lc; string defaultText; string defaultSelectedValue; Action<string> selectChanged; CascadeQuery subQuery; /// <summary> /// 多级联动查询 /// </summary> /// <param name="lc">控件</param> /// <param name="defaultText">默认文本</param> /// <param name="defaultSelectedValue">默认选中的值</param> /// <param name="selectChanged">选择变更时执行的方法</param> /// <param name="subQuery">子查询</param> public CascadeQuery(ListControl lc, string defaultText, string defaultSelectedValue, Action<string> selectChanged, CascadeQuery subQuery) { this.lc = lc; this.defaultText = defaultText; this.defaultSelectedValue = defaultSelectedValue; this.selectChanged = selectChanged; this.subQuery = subQuery; Anthem.DropDownList ddl = lc as Anthem.DropDownList; if (ddl != null) { ddl.AutoUpdateAfterCallBack = true; if (!ddl.Page.ClientScript.IsStartupScriptRegistered("cascadeQuery")) { ddl.Page.ClientScript.RegisterStartupScript( ddl.Page.GetType(), "cascadeQuery", ///选择默认选项时,取消回发 ///if (ddl.selectedIndex<=0) return false; ///添加客户端脚本,用于选择变更时,设置子查询的控件默认选项为 正在查询 @"function onCascadeQuery(id, ddl) { var el = document.getElementById(id); el.options.length = 0; el.options.add(new Option('正在查询...', '')); }", true); } if (subQuery != null) { //只有子查询时才启用回发 ddl.AutoCallBack = true; ddl.PreCallBackFunction = string.Format(@"function(ddl) {{onCascadeQuery('{0}',ddl);}}", subQuery.lc.ClientID); } } else { if (subQuery != null) { lc.AutoPostBack = true; } } //绑定选择变更事件 this.lc.SelectedIndexChanged += new EventHandler(lc_SelectedIndexChanged); //页面第一次加载时,为控件添加默认选项 if (!lc.Page.IsPostBack) ResetSelect(); } void lc_SelectedIndexChanged(object sender, EventArgs e) { SelectChange(); } /// <summary> /// 选择变更时执行 /// </summary> void SelectChange() { ResetSubSelect();//// if (lc.SelectedIndex > 0) { if (selectChanged != null) { selectChanged(lc.SelectedValue); //执行选择变更的方法,并且递归到每个子查询 if (subQuery != null && subQuery.lc.Visible) subQuery.SelectChange(); } } } /// <summary> /// 重置控件(清空所有项,并加入默认选项) /// </summary> void ResetSelect() { lc.Items.Clear(); InsertDefaultItem(); ResetSubSelect(); } /// <summary> /// 递归重置子查询的控件 /// </summary> void ResetSubSelect() { if (subQuery != null) subQuery.ResetSelect(); } /// <summary> /// 插入默认选项 /// </summary> void InsertDefaultItem() { lc.Items.Insert(0, new ListItem(defaultText, string.Empty)); } /// <summary> /// 设置默认选中(仅当页面第一次加载时) /// </summary> void SetDefaultSelected() { if (!lc.Page.IsPostBack) { SetSelectedValue(defaultSelectedValue); } } /// <summary> /// 绑定数据 /// </summary> /// <param name="dataSource">数据源</param> /// <param name="textfld">文本字段</param> /// <param name="valuefld">值字段</param> public void BindData(object dataSource, string textfld, string valuefld) { lc.DataSource = dataSource; lc.DataTextField = textfld; lc.DataValueField = valuefld; lc.DataBind(); InsertDefaultItem(); SetDefaultSelected(); } /// <summary> /// 设置选中的值 /// </summary> /// <param name="value">值</param> public void SetSelectedValue(string value) { //lc.SelectedValue = value; ListItem item = lc.Items.FindByValue(value); if (item != null) { lc.ClearSelection(); item.Selected = true; SelectChange(); } } }
目前支持Anthem.DropDownList以及继承自ListControl的控件,可根据实际需要进行修改。
关键演示代码如下:
aspx:
<anthem:DropDownList runat="server" Id="a1" /> <anthem:DropDownList runat="server" Id="a2" /> <anthem:DropDownList runat="server" Id="a3" />
aspx.cs:
CascadeQuery cq3; CascadeQuery cq2; CascadeQuery cq1; protected void Page_Load(object sender, EventArgs e) { cq3 = new CascadeQuery(a3, "SelectThird", string.Empty, null, null); cq2 = new CascadeQuery(a2, "SelectSecond", string.Empty, A2Change, cq3); cq1 = new CascadeQuery(a1, "SelectFirst", "3", A1Change, cq2); if (!IsPostBack) BindA1(); } DataTable GenerateData(int l) { DataTable table = new DataTable(); table.Columns.Add("value"); table.Columns.Add("text"); for (int i = 0; i < 10; i++) { string value = (i * l).ToString(); table.Rows.Add(value, "text-" + value); } return table; } void BindA1() { cq1.BindData(GenerateData(1), "text", "value"); } void A1Change(string value) { cq2.BindData(GenerateData(int.Parse(value)), "text", "value"); cq2.SetSelectedValue("6"); } void A2Change(string value) { cq3.BindData(GenerateData(int.Parse(value)), "text", "value"); }
代码下载:点击这里
打完收工,睡觉~