using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; [assembly: TagPrefix("WebApplication", "MyControl")] namespace WebApplication1 { [ToolboxData("<{0}:LinkedDropDownList runat=server></{0}:LinkedDropDownList>")] public class LinkedDropDownList : DropDownList//继承自基本的DropDownList { private DropDownList _linkedDropDownList; public LinkedDropDownList() { this.SelectedIndexChanged += new EventHandler(LinkedDropDownList_SelectedIndexChanged);//添加自己的SelectedIndexChanged事件 this.AutoPostBack = true;//强制设置自己的AutoPostBack为true } //下面两个事件都作为获取数据源的事件 public event EventHandler BindData;//这个事件为绑定父DropDownList public event Action<object, DropDownListIndexChangeEventArg> BindLinkedData;//这个事件为绑定子DropDownList protected void LinkedDropDownList_SelectedIndexChanged(object sender, EventArgs e) { if (this.BindLinkedData != null) { this._linkedDropDownList = this.NamingContainer.FindControl(this.NextDropDownListID) as DropDownList;//从控件容器中找出子下拉菜单 var newE = new DropDownListIndexChangeEventArg(this.SelectedValue, this.SelectedItem.Text, this.SelectedIndex,this._linkedDropDownList); BindLinkedData(this, newE); } //如果子DropDownList本身也为联动DropDownList 执行子DropDownList的绑定 var next = this.NamingContainer.FindControl(this.NextDropDownListID) as LinkedDropDownList; if (next != null) { next.OnSelectedIndexChanged(EventArgs.Empty); } } //重写OnLoad使得可以发生数据绑定 protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (this.BindData != null && !Page.IsPostBack) { BindData(this, EventArgs.Empty); this.SelectedIndex = 0; } if (this.BindLinkedData != null &&!Page.IsPostBack) { this._linkedDropDownList = this.NamingContainer.FindControl(this.NextDropDownListID) as DropDownList; var newE = new DropDownListIndexChangeEventArg(this.SelectedValue, this.SelectedItem.Text, this.SelectedIndex, this._linkedDropDownList); BindLinkedData(this, newE); } } //子DropDownList的ID public string NextDropDownListID { get { return ViewState[this.ID + "LinkedDropDownList"] as string;//加上自身的ID做唯一标示 } set { ViewState[this.ID + "LinkedDropDownList"] = value; } } } //事件参数 方便绑定子菜单时候得到数据源绑定参数 public class DropDownListIndexChangeEventArg : EventArgs { private readonly string _selectedValue = null; private readonly string _selectedText = null; private readonly int _selectedIndex; private readonly DropDownList _nextDropDownList = null; public DropDownListIndexChangeEventArg(string selectedValue, string selectedText, int selectedIndex,DropDownList nextDropDownList) { this._selectedValue = selectedValue; this._selectedText = selectedText; this._selectedIndex = selectedIndex; this._nextDropDownList = nextDropDownList; } public string SelectedValue { get { return this._selectedValue; } } public string SelectedText { get { return this._selectedText; } } public int SelectedIndex { get { return this._selectedIndex; } } public DropDownList NextDropDownList { get { return this._nextDropDownList; } } } }
调用代码:
首先我们需要一个Mock类来产生绑定的数据 下面是Mock类的代码
using System; using System.Data; using System.Configuration; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; using System.Collections.Generic; namespace WebApplication1 { public class MockData { public Dictionary<int,string> GetRootData() { var returnValue = new Dictionary<int, string>(); returnValue.Add(1, "a"); returnValue.Add(2, "b"); returnValue.Add(3, "c"); return returnValue; } public Dictionary<string,string> GetLinkedData(string value) { var intValue = int.Parse(value); var returnValue = new Dictionary<string, string>(); returnValue.Add(value, value); returnValue.Add((intValue + 1).ToString(), (intValue + 1).ToString()); return returnValue; } public Dictionary<int, int> GetLinkedData(int value) { var returnValue = new Dictionary<int, int>(); returnValue.Add(value + 1, value + 1); return returnValue; } } }
这里演示了两种调用 一种是三级联动 一种是在数据绑定控件Repeater里面的联动 先是前台代码
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %> <%@ Register Assembly="WebApplication1" Namespace="WebApplication1" TagPrefix="cc1" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <cc1:LinkedDropDownList ID="LinkedDropDownList1" runat="server" NextDropDownListID="LinkedDropDownList2"> </cc1:LinkedDropDownList> <cc1:LinkedDropDownList ID="LinkedDropDownList2" runat="server" NextDropDownListID="NextDropDownList2"> </cc1:LinkedDropDownList> <asp:DropDownList ID="NextDropDownList2" runat="server"> </asp:DropDownList> <asp:Repeater ID="RPTTest" runat="server"> <HeaderTemplate> </HeaderTemplate> <ItemTemplate> <cc1:LinkedDropDownList ID="TestLinkedInRepeater" runat="server" NextDropDownListID="DDLNext" OnBindData="LinkedDropDownList1_BindData" OnBindLinkedData="LinkedDropDownList1_BindLinkedData"> </cc1:LinkedDropDownList> <asp:DropDownList ID="DDLNext" runat="server"> </asp:DropDownList> </ItemTemplate> <FooterTemplate> </FooterTemplate> </asp:Repeater> </form> </body> </html>
后台代码
using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; using System.Collections.Generic; namespace WebApplication1 { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //所有绑定事件最后都是用的同一套代码 LinkedDropDownList1.BindData += new EventHandler(LinkedDropDownList1_BindData); LinkedDropDownList1.BindLinkedData += new Action<object, DropDownListIndexChangeEventArg>(LinkedDropDownList1_BindLinkedData); LinkedDropDownList2.BindLinkedData += new Action<object, DropDownListIndexChangeEventArg>(LinkedDropDownList2_BindLinkedData);//对于三级绑定 只需要写绑定子菜单的事件就可以 if(!IsPostBack)//给Repeater一个数据源 { var rptDataSource = new List<string>() { "0", "0", "0" }; RPTTest.DataSource = rptDataSource; RPTTest.DataBind(); } } //所以绑定只需要考虑数据获取和绑定即可 不需要考虑IsPostBack,FindControl等问题 protected void LinkedDropDownList1_BindLinkedData(object arg1, DropDownListIndexChangeEventArg arg2) { var mock = new MockData(); var dataSource = mock.GetLinkedData(arg2.SelectedValue); arg2.NextDropDownList.DataSource = dataSource; arg2.NextDropDownList.DataTextField = "Value"; arg2.NextDropDownList.DataValueField = "Key"; arg2.NextDropDownList.DataBind(); } protected void LinkedDropDownList1_BindData(object sender, EventArgs e) { var mock = new MockData(); var ddl = sender as DropDownList; ddl.DataSource = mock.GetRootData(); ddl.DataTextField = "Value"; ddl.DataValueField = "Key"; ddl.DataBind(); } void LinkedDropDownList2_BindLinkedData(object arg1, DropDownListIndexChangeEventArg arg2) { var mock = new MockData(); var dataSource = mock.GetLinkedData(int.Parse(arg2.SelectedValue)); arg2.NextDropDownList.DataSource = dataSource; arg2.NextDropDownList.DataTextField = "Value"; arg2.NextDropDownList.DataValueField = "Key"; arg2.NextDropDownList.DataBind(); } } }
此文章系转载,点这里查看原文。