刚好手头有需要用到多级联动的功能,平常写一堆代码用于数据绑定、事件绑定,实在太烦琐了,于是想办法简化一下,也顺便练练手~_~
实现比较简单,不多说,具体代码如下:
001 |
using System;
|
002 |
using System.Web.UI.WebControls;
|
003 |
004 |
/// <summary> |
005 |
/// 多级联动查询 |
006 |
/// </summary> |
007 |
public class CascadeQuery
|
008 |
{ |
009 |
ListControl lc;
|
010 |
string defaultText;
|
011 |
string defaultSelectedValue;
|
012 |
Action<string> selectChanged;
|
013 |
CascadeQuery subQuery;
|
014 |
015 |
/// <summary>
|
016 |
/// 多级联动查询
|
017 |
/// </summary>
|
018 |
/// <param name="lc">控件</param>
|
019 |
/// <param name="defaultText">默认文本</param>
|
020 |
/// <param name="defaultSelectedValue">默认选中的值</param>
|
021 |
/// <param name="selectChanged">选择变更时执行的方法</param>
|
022 |
/// <param name="subQuery">子查询</param>
|
023 |
public CascadeQuery(ListControl lc, string defaultText, string defaultSelectedValue, Action<string> selectChanged, CascadeQuery subQuery)
|
024 |
{
|
025 |
this.lc = lc;
|
026 |
this.defaultText = defaultText;
|
027 |
this.defaultSelectedValue = defaultSelectedValue;
|
028 |
this.selectChanged = selectChanged;
|
029 |
this.subQuery = subQuery;
|
030 |
031 |
Anthem.DropDownList ddl = lc as Anthem.DropDownList;
|
032 |
if (ddl != null)
|
033 |
{
|
034 |
ddl.AutoUpdateAfterCallBack = true;
|
035 |
if (!ddl.Page.ClientScript.IsStartupScriptRegistered("cascadeQuery"))
|
036 |
{
|
037 |
ddl.Page.ClientScript.RegisterStartupScript(
|
038 |
ddl.Page.GetType(),
|
039 |
"cascadeQuery",
|
040 |
///选择默认选项时,取消回发
|
041 |
///if (ddl.selectedIndex<=0) return false;
|
042 |
///添加客户端脚本,用于选择变更时,设置子查询的控件默认选项为 正在查询
|
043 |
@"function onCascadeQuery(id, ddl) {
|
044 |
var el = document.getElementById(id);
|
045 |
el.options.length = 0;
|
046 |
el.options.add(new Option('正在查询...', ''));
|
047 |
}",
|
048 |
true);
|
049 |
}
|
050 |
051 |
if (subQuery != null)
|
052 |
{
|
053 |
//只有子查询时才启用回发
|
054 |
ddl.AutoCallBack = true;
|
055 |
ddl.PreCallBackFunction = string.Format(@"function(ddl) {{onCascadeQuery('{0}',ddl);}}", subQuery.lc.ClientID);
|
056 |
}
|
057 |
}
|
058 |
else
|
059 |
{
|
060 |
if (subQuery != null)
|
061 |
{
|
062 |
lc.AutoPostBack = true;
|
063 |
}
|
064 |
}
|
065 |
066 |
//绑定选择变更事件
|
067 |
this.lc.SelectedIndexChanged += new EventHandler(lc_SelectedIndexChanged);
|
068 |
//页面第一次加载时,为控件添加默认选项
|
069 |
if (!lc.Page.IsPostBack)
|
070 |
ResetSelect();
|
071 |
}
|
072 |
073 |
void lc_SelectedIndexChanged(object sender, EventArgs e)
|
074 |
{
|
075 |
SelectChange();
|
076 |
}
|
077 |
078 |
/// <summary>
|
079 |
/// 选择变更时执行
|
080 |
/// </summary>
|
081 |
void SelectChange()
|
082 |
{
|
083 |
ResetSubSelect();////
|
084 |
085 |
if (lc.SelectedIndex > 0)
|
086 |
{
|
087 |
if (selectChanged != null)
|
088 |
{
|
089 |
selectChanged(lc.SelectedValue);
|
090 |
//执行选择变更的方法,并且递归到每个子查询
|
091 |
if (subQuery != null && subQuery.lc.Visible)
|
092 |
subQuery.SelectChange();
|
093 |
}
|
094 |
}
|
095 |
}
|
096 |
097 |
/// <summary>
|
098 |
/// 重置控件(清空所有项,并加入默认选项)
|
099 |
/// </summary>
|
100 |
void ResetSelect()
|
101 |
{
|
102 |
lc.Items.Clear();
|
103 |
InsertDefaultItem();
|
104 |
ResetSubSelect();
|
105 |
}
|
106 |
107 |
/// <summary>
|
108 |
/// 递归重置子查询的控件
|
109 |
/// </summary>
|
110 |
void ResetSubSelect()
|
111 |
{
|
112 |
if (subQuery != null)
|
113 |
subQuery.ResetSelect();
|
114 |
}
|
115 |
|
116 |
/// <summary>
|
117 |
/// 插入默认选项
|
118 |
/// </summary>
|
119 |
void InsertDefaultItem()
|
120 |
{
|
121 |
lc.Items.Insert(0, new ListItem(defaultText, string.Empty));
|
122 |
}
|
123 |
124 |
/// <summary>
|
125 |
/// 设置默认选中(仅当页面第一次加载时)
|
126 |
/// </summary>
|
127 |
void SetDefaultSelected()
|
128 |
{
|
129 |
if (!lc.Page.IsPostBack)
|
130 |
{
|
131 |
SetSelectedValue(defaultSelectedValue);
|
132 |
}
|
133 |
}
|
134 |
135 |
/// <summary>
|
136 |
/// 绑定数据
|
137 |
/// </summary>
|
138 |
/// <param name="dataSource">数据源</param>
|
139 |
/// <param name="textfld">文本字段</param>
|
140 |
/// <param name="valuefld">值字段</param>
|
141 |
public void BindData(object dataSource, string textfld, string valuefld)
|
142 |
{
|
143 |
lc.DataSource = dataSource;
|
144 |
lc.DataTextField = textfld;
|
145 |
lc.DataValueField = valuefld;
|
146 |
lc.DataBind();
|
147 |
InsertDefaultItem();
|
148 |
SetDefaultSelected();
|
149 |
}
|
150 |
151 |
/// <summary>
|
152 |
/// 设置选中的值
|
153 |
/// </summary>
|
154 |
/// <param name="value">值</param>
|
155 |
public void SetSelectedValue(string value)
|
156 |
{
|
157 |
//lc.SelectedValue = value;
|
158 |
ListItem item = lc.Items.FindByValue(value);
|
159 |
if (item != null)
|
160 |
{
|
161 |
lc.ClearSelection();
|
162 |
item.Selected = true;
|
163 |
SelectChange();
|
164 |
}
|
165 |
}
|
166 |
} |
目前支持Anthem.DropDownList以及继承自ListControl的控件,可根据实际需要进行修改。
关键演示代码如下:
aspx:
1 |
<anthem:DropDownList runat="server" Id="a1" />
|
2 |
<anthem:DropDownList runat="server" Id="a2" />
|
3 |
<anthem:DropDownList runat="server" Id="a3" />
|
aspx.cs:
01 |
CascadeQuery cq3; |
02 |
CascadeQuery cq2; |
03 |
CascadeQuery cq1; |
04 |
protected void Page_Load(object sender, EventArgs e)
|
05 |
{ |
06 |
cq3 = new CascadeQuery(a3, "SelectThird", string.Empty, null, null);
|
07 |
cq2 = new CascadeQuery(a2, "SelectSecond", string.Empty, A2Change, cq3);
|
08 |
cq1 = new CascadeQuery(a1, "SelectFirst", "3", A1Change, cq2);
|
09 |
if (!IsPostBack)
|
10 |
BindA1();
|
11 |
} |
12 |
13 |
DataTable GenerateData(int l)
|
14 |
{ |
15 |
DataTable table = new DataTable();
|
16 |
table.Columns.Add("value");
|
17 |
table.Columns.Add("text");
|
18 |
for (int i = 0; i < 10; i++)
|
19 |
{
|
20 |
string value = (i * l).ToString();
|
21 |
table.Rows.Add(value, "text-" + value);
|
22 |
}
|
23 |
return table;
|
24 |
} |
25 |
26 |
void BindA1()
|
27 |
{ |
28 |
cq1.BindData(GenerateData(1), "text", "value");
|
29 |
} |
30 |
31 |
void A1Change(string value)
|
32 |
{ |
33 |
cq2.BindData(GenerateData(int.Parse(value)), "text", "value");
|
34 |
cq2.SetSelectedValue("6");
|
35 |
} |
36 |
37 |
void A2Change(string value)
|
38 |
{ |
39 |
cq3.BindData(GenerateData(int.Parse(value)), "text", "value");
|
40 |
} |
代码下载:点击这里
打完收工,睡觉~
作者:囧月
出处:http://lwme.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
刚好手头有需要用到多级联动的功能,平常写一堆代码用于数据绑定、事件绑定,实在太烦琐了,于是想办法简化一下,也顺便练练手~_~
实现比较简单,不多说,具体代码如下:
001 |
using System;
|
002 |
using System.Web.UI.WebControls;
|
003 |
004 |
/// <summary> |
005 |
/// 多级联动查询 |
006 |
/// </summary> |
007 |
public class CascadeQuery
|
008 |
{ |
009 |
ListControl lc;
|
010 |
string defaultText;
|
011 |
string defaultSelectedValue;
|
012 |
Action<string> selectChanged;
|
013 |
CascadeQuery subQuery;
|
014 |
015 |
/// <summary>
|
016 |
/// 多级联动查询
|
017 |
/// </summary>
|
018 |
/// <param name="lc">控件</param>
|
019 |
/// <param name="defaultText">默认文本</param>
|
020 |
/// <param name="defaultSelectedValue">默认选中的值</param>
|
021 |
/// <param name="selectChanged">选择变更时执行的方法</param>
|
022 |
/// <param name="subQuery">子查询</param>
|
023 |
public CascadeQuery(ListControl lc, string defaultText, string defaultSelectedValue, Action<string> selectChanged, CascadeQuery subQuery)
|
024 |
{
|
025 |
this.lc = lc;
|
026 |
this.defaultText = defaultText;
|
027 |
this.defaultSelectedValue = defaultSelectedValue;
|
028 |
this.selectChanged = selectChanged;
|
029 |
this.subQuery = subQuery;
|
030 |
031 |
Anthem.DropDownList ddl = lc as Anthem.DropDownList;
|
032 |
if (ddl != null)
|
033 |
{
|
034 |
ddl.AutoUpdateAfterCallBack = true;
|
035 |
if (!ddl.Page.ClientScript.IsStartupScriptRegistered("cascadeQuery"))
|
036 |
{
|
037 |
ddl.Page.ClientScript.RegisterStartupScript(
|
038 |
ddl.Page.GetType(),
|
039 |
"cascadeQuery",
|
040 |
///选择默认选项时,取消回发
|
041 |
///if (ddl.selectedIndex<=0) return false;
|
042 |
///添加客户端脚本,用于选择变更时,设置子查询的控件默认选项为 正在查询
|
043 |
@"function onCascadeQuery(id, ddl) {
|
044 |
var el = document.getElementById(id);
|
045 |
el.options.length = 0;
|
046 |
el.options.add(new Option('正在查询...', ''));
|
047 |
}",
|
048 |
true);
|
049 |
}
|
050 |
051 |
if (subQuery != null)
|
052 |
{
|
053 |
//只有子查询时才启用回发
|
054 |
ddl.AutoCallBack = true;
|
055 |
ddl.PreCallBackFunction = string.Format(@"function(ddl) {{onCascadeQuery('{0}',ddl);}}", subQuery.lc.ClientID);
|
056 |
}
|
057 |
}
|
058 |
else
|
059 |
{
|
060 |
if (subQuery != null)
|
061 |
{
|
062 |
lc.AutoPostBack = true;
|
063 |
}
|
064 |
}
|
065 |
066 |
//绑定选择变更事件
|
067 |
this.lc.SelectedIndexChanged += new EventHandler(lc_SelectedIndexChanged);
|
068 |
//页面第一次加载时,为控件添加默认选项
|
069 |
if (!lc.Page.IsPostBack)
|
070 |
ResetSelect();
|
071 |
}
|
072 |
073 |
void lc_SelectedIndexChanged(object sender, EventArgs e)
|
074 |
{
|
075 |
SelectChange();
|
076 |
}
|
077 |
078 |
/// <summary>
|
079 |
/// 选择变更时执行
|
080 |
/// </summary>
|
081 |
void SelectChange()
|
082 |
{
|
083 |
ResetSubSelect();////
|
084 |
085 |
if (lc.SelectedIndex > 0)
|
086 |
{
|
087 |
if (selectChanged != null)
|
088 |
{
|
089 |
selectChanged(lc.SelectedValue);
|
090 |
//执行选择变更的方法,并且递归到每个子查询
|
091 |
if (subQuery != null && subQuery.lc.Visible)
|
092 |
subQuery.SelectChange();
|
093 |
}
|
094 |
}
|
095 |
}
|
096 |
097 |
/// <summary>
|
098 |
/// 重置控件(清空所有项,并加入默认选项)
|
099 |
/// </summary>
|
100 |
void ResetSelect()
|
101 |
{
|
102 |
lc.Items.Clear();
|
103 |
InsertDefaultItem();
|
104 |
ResetSubSelect();
|
105 |
}
|
106 |
107 |
/// <summary>
|
108 |
/// 递归重置子查询的控件
|
109 |
/// </summary>
|
110 |
void ResetSubSelect()
|
111 |
{
|
112 |
if (subQuery != null)
|
113 |
subQuery.ResetSelect();
|
114 |
}
|
115 |
|
116 |
/// <summary>
|
117 |
/// 插入默认选项
|
118 |
/// </summary>
|
119 |
void InsertDefaultItem()
|
120 |
{
|
121 |
lc.Items.Insert(0, new ListItem(defaultText, string.Empty));
|
122 |
}
|
123 |
124 |
/// <summary>
|
125 |
/// 设置默认选中(仅当页面第一次加载时)
|
126 |
/// </summary>
|
127 |
void SetDefaultSelected()
|
128 |
{
|
129 |
if (!lc.Page.IsPostBack)
|
130 |
{
|
131 |
SetSelectedValue(defaultSelectedValue);
|
132 |
}
|
133 |
}
|
134 |
135 |
/// <summary>
|
136 |
/// 绑定数据
|
137 |
/// </summary>
|
138 |
/// <param name="dataSource">数据源</param>
|
139 |
/// <param name="textfld">文本字段</param>
|
140 |
/// <param name="valuefld">值字段</param>
|
141 |
public void BindData(object dataSource, string textfld, string valuefld)
|
142 |
{
|
143 |
lc.DataSource = dataSource;
|
144 |
lc.DataTextField = textfld;
|
145 |
lc.DataValueField = valuefld;
|
146 |
lc.DataBind();
|
147 |
InsertDefaultItem();
|
148 |
SetDefaultSelected();
|
149 |
}
|
150 |
151 |
/// <summary>
|
152 |
/// 设置选中的值
|
153 |
/// </summary>
|
154 |
/// <param name="value">值</param>
|
155 |
public void SetSelectedValue(string value)
|
156 |
{
|
157 |
//lc.SelectedValue = value;
|
158 |
ListItem item = lc.Items.FindByValue(value);
|
159 |
if (item != null)
|
160 |
{
|
161 |
lc.ClearSelection();
|
162 |
item.Selected = true;
|
163 |
SelectChange();
|
164 |
}
|
165 |
}
|
166 |
} |
目前支持Anthem.DropDownList以及继承自ListControl的控件,可根据实际需要进行修改。
关键演示代码如下:
aspx:
1 |
<anthem:DropDownList runat="server" Id="a1" />
|
2 |
<anthem:DropDownList runat="server" Id="a2" />
|
3 |
<anthem:DropDownList runat="server" Id="a3" />
|
aspx.cs:
01 |
CascadeQuery cq3; |
02 |
CascadeQuery cq2; |
03 |
CascadeQuery cq1; |
04 |
protected void Page_Load(object sender, EventArgs e)
|
05 |
{ |
06 |
cq3 = new CascadeQuery(a3, "SelectThird", string.Empty, null, null);
|
07 |
cq2 = new CascadeQuery(a2, "SelectSecond", string.Empty, A2Change, cq3);
|
08 |
cq1 = new CascadeQuery(a1, "SelectFirst", "3", A1Change, cq2);
|
09 |
if (!IsPostBack)
|
10 |
BindA1();
|
11 |
} |
12 |
13 |
DataTable GenerateData(int l)
|
14 |
{ |
15 |
DataTable table = new DataTable();
|
16 |
table.Columns.Add("value");
|
17 |
table.Columns.Add("text");
|
18 |
for (int i = 0; i < 10; i++)
|
19 |
{
|
20 |
string value = (i * l).ToString();
|
21 |
table.Rows.Add(value, "text-" + value);
|
22 |
}
|
23 |
return table;
|
24 |
} |
25 |
26 |
void BindA1()
|
27 |
{ |
28 |
cq1.BindData(GenerateData(1), "text", "value");
|
29 |
} |
30 |
31 |
void A1Change(string value)
|
32 |
{ |
33 |
cq2.BindData(GenerateData(int.Parse(value)), "text", "value");
|
34 |
cq2.SetSelectedValue("6");
|
35 |
} |
36 |
37 |
void A2Change(string value)
|
38 |
{ |
39 |
cq3.BindData(GenerateData(int.Parse(value)), "text", "value");
|
40 |
} |
代码下载:点击这里
打完收工,睡觉~