刚好手头有需要用到多级联动的功能,平常写一堆代码用于数据绑定、事件绑定,实在太烦琐了,于是想办法简化一下,也顺便练练手~_~
实现比较简单,不多说,具体代码如下:
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");
}
代码下载:点击这里
打完收工,睡觉~