两个DropDownList在Repeater、DataList、DataGrid内的连动和冒泡事件(BubbleEvent)
问题
: http://community.csdn.net/Expert/topic/4670/4670056.xml?temp=3.944033E-02
刚看第一眼觉得在第一个DDL的SelectedIndexChanged事件内绑定第二个DDL就ok了,页面上写或者ItemDataBound内写事件挂接代码都可以。打开VS写测试却发现有点
障碍哦,
在SelectedIndexChanged内要知道去绑定哪个行哪个列的DDL要费些周折。
只有从DDL一级一级的向上找Parent最后找到DataGridItem,再利用其ItemIndex定位到行然后FindControl到要绑定的DDL,最终可以实现,好像比较累哦。
随又想到DataGrid的ItemCommand事件,但发现WebControl内只有
Button
ImageButton
LinkButton有 CommandName属性和 CommandArgument属性,并可以将事件
上浮(冒泡). DropDownList先天不足!真是郁闷~~~~~ 能不能自己改造呢?
动手试试就知道了。
[Copy to clipboard]
using System; using System.ComponentModel; using System.Web.UI.WebControls; namespace AspxBoy.WebTest.MyControls { /// <summary> /// CommandableDropDownList 的摘要说明。 /// </summary> public class CommandableDropDownList : DropDownList { #region 字段 #endregion #region 属性 [ Browsable(true), DefaultValue("") ] public string CommandName { get { return ViewState["CommandName"] == null ? String.Empty : ViewState["CommandName"].ToString(); } set { ViewState["CommandName"] = value; } } [ Browsable(true), DefaultValue("") ] public string CommandArgument { get { return ViewState["CommandArgument"] == null ? String.Empty : ViewState["CommandArgument"].ToString(); } set { ViewState["CommandArgument"] = value; } } #endregion #region 构造器 public CommandableDropDownList() { // // TODO: 在此处添加构造函数逻辑 // } #endregion #region 事件 private static object _commandEvent = new object(); public event CommandEventHandler SelectedChangedCommand { add { Events.AddHandler(_commandEvent,value); } remove { Events.RemoveHandler(_commandEvent,value); } } protected virtual void OnCommand(CommandEventArgs e) { CommandEventHandler commandHander = (CommandEventHandler)Events[_commandEvent]; if(commandHander != null) { commandHander(this,e); } else { base.RaiseBubbleEvent(this,e); } } #endregion #region 覆写的方法 protected override void OnSelectedIndexChanged(EventArgs e) { base.OnSelectedIndexChanged (e); if(this.AutoPostBack) { CommandEventArgs args = new CommandEventArgs(this.CommandName, this.CommandArgument); OnCommand(args); } } #endregion } }
就这样了,然后在模板列内放置该控件,DataGrid的ItemCommand事件内就可以处理到CommandName为你指定的值的操作拉
后台代码如下:
[Copy to clipboard]
using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using AspxBoy.WebTest.MyControls; namespace AspxBoy.WebTest { /// <summary> /// TwoDropDownListInDataGridEx 的摘要说明。 /// </summary> public class TwoDropDownListInDataGridEx : System.Web.UI.Page { protected System.Web.UI.WebControls.DataGrid dg; private void Page_Load(object sender, System.EventArgs e) { // 在此处放置用户代码以初始化页面 if(!Page.IsPostBack) { BindGrid(); } } private void BindGrid() { dg.DataSource = new string[]{"a","a","a","a","a","a"}; dg.DataBind(); } #region Web 窗体设计器生成的代码 override protected void OnInit(EventArgs e) { // // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。 // InitializeComponent(); base.OnInit(e); } /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.dg.ItemCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.dg_ItemCommand); this.dg.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.dg_ItemDataBound); this.Load += new System.EventHandler(this.Page_Load); } #endregion private ICollection GetProvinceCollection() { return new string[]{"陕西","辽宁"}; } private ICollection GetCityCollection(string provinceName) { if(provinceName == "陕西") { return new string[]{"西安","宝鸡","渭南","汉中"}; } else if(provinceName == "辽宁") { return new string[]{"沈阳","鞍山","抚顺","本溪"}; } else { return null; } } private void dg_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e) { if(e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item) { Label lbl = e.Item.FindControl("lbl_no") as Label; if( lbl != null ) { lbl.Text = (e.Item.ItemIndex + 1).ToString(); } CommandableDropDownList ddl_province = e.Item.FindControl("ddl_province") as CommandableDropDownList; if(ddl_province != null) { ddl_province.DataSource = GetProvinceCollection(); ddl_province.DataBind(); } CommandableDropDownList ddl_city = e.Item.FindControl("ddl_city") as CommandableDropDownList; if(ddl_city != null) { ddl_city.DataSource = GetCityCollection(ddl_province.SelectedValue); ddl_city.DataBind(); } } } private void dg_ItemCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e) { if(e.CommandName == "ProvinceChange") { string currentProvinceName = String.Empty; int index = e.Item.ItemIndex; CommandableDropDownList ddl = this.dg.Items[index].FindControl("ddl_province") as CommandableDropDownList; if(ddl != null) { currentProvinceName = ddl.SelectedValue; } ddl = this.dg.Items[index].FindControl("ddl_city") as CommandableDropDownList; if(ddl != null) { ICollection cityCollection = GetCityCollection(currentProvinceName); if(cityCollection != null) { ddl.DataSource = cityCollection; ddl.DataBind(); } } } } } }
aspx代码如下
[Copy to clipboard]
<%@ Page language="c#" Codebehind="TwoDropDownListInDataGridEx.aspx.cs" AutoEventWireup="false" Inherits="AspxBoy.WebTest.TwoDropDownListInDataGridEx" %> <%@ Register TagPrefix="cc1" Namespace="AspxBoy.WebTest.MyControls" Assembly="AspxBoy.WebTest" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <HTML> <HEAD> <title>TwoDropDownListInDataGridEx</title> <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1"> <meta name="CODE_LANGUAGE" Content="C#"> <meta name="vs_defaultClientScript" content="JavaScript"> <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <asp:DataGrid id="dg" style="Z-INDEX: 101; LEFT: 112px; POSITION: absolute; TOP: 80px" runat="server" Width="416px" AutoGenerateColumns="False" Height="16px"> <Columns> <asp:TemplateColumn HeaderText="NO."> <ItemTemplate> <asp:Label runat="server" id="lbl_no"></asp:Label> </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn HeaderText="Province" FooterText="Province"> <ItemTemplate> <cc1:CommandableDropDownList id="ddl_province" runat="server" AutoPostBack="true" CommandName="ProvinceChange"></cc1:CommandableDropDownList> </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn HeaderText="City" FooterText="City"> <ItemTemplate> <cc1:CommandableDropDownList id="ddl_city" runat="server"></cc1:CommandableDropDownList> </ItemTemplate> </asp:TemplateColumn> </Columns> </asp:DataGrid> </form> </body> </HTML>
若不使用自定义控件,的代码如下(比较累哦
):
[Copy to clipboard]
using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; namespace AspxBoy.WebTest { /// <summary> /// TwoDropDownListInDataGrid 的摘要说明。 /// </summary> public class TwoDropDownListInDataGrid : System.Web.UI.Page { protected System.Web.UI.WebControls.DataGrid dg; private void Page_Load(object sender, System.EventArgs e) { // 在此处放置用户代码以初始化页面 if(!Page.IsPostBack) { BindGrid(); } } private void BindGrid() { dg.DataSource = new string[]{"a","a","a","a","a","a"}; dg.DataBind(); } private ICollection GetProvinceCollection() { return new string[]{"陕西","辽宁"}; } private ICollection GetCityCollection(string provinceName) { if(provinceName == "陕西") { return new string[]{"西安","宝鸡","渭南","汉中"}; } else if(provinceName == "辽宁") { return new string[]{"沈阳","鞍山","抚顺","本溪"}; } else { return null; } } #region Web 窗体设计器生成的代码 override protected void OnInit(EventArgs e) { // // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。 // InitializeComponent(); base.OnInit(e); } /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.dg.ItemCreated += new System.Web.UI.WebControls.DataGridItemEventHandler(this.dg_ItemCreated); this.dg.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.dg_ItemDataBound); this.Load += new System.EventHandler(this.Page_Load); } #endregion private void dg_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e) { if(e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item) { Label lbl = e.Item.FindControl("lbl_no") as Label; if( lbl != null ) { lbl.Text = (e.Item.ItemIndex + 1).ToString(); } DropDownList ddl_province = e.Item.FindControl("ddl_province") as DropDownList; if(ddl_province != null) { ddl_province.DataSource = GetProvinceCollection(); ddl_province.DataBind(); } DropDownList ddl_city = e.Item.FindControl("ddl_city") as DropDownList; if(ddl_city != null) { ddl_city.DataSource = GetCityCollection(ddl_province.SelectedValue); ddl_city.DataBind(); } } } private void dg_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e) { if(e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item) { DropDownList ddl = e.Item.FindControl("ddl_province") as DropDownList; if(ddl != null) { ddl.AutoPostBack = true; ddl.SelectedIndexChanged += new EventHandler(ddl_SelectedIndexChanged); } } } protected void ddl_SelectedIndexChanged(object o , EventArgs e) { DropDownList ddl = o as DropDownList; if(ddl != null) { TableCell cell = ddl.Parent as TableCell; if(cell != null) { DataGridItem dgItem = cell.Parent as DataGridItem; if(dgItem != null) { string currentProvinceName = String.Empty; int index = dgItem.ItemIndex; ddl = this.dg.Items[index].FindControl("ddl_province") as DropDownList; if(ddl != null) { currentProvinceName = ddl.SelectedValue; } ddl = this.dg.Items[index].FindControl("ddl_city") as DropDownList; if(ddl != null) { ICollection cityCollection = GetCityCollection(currentProvinceName); if(cityCollection != null) { ddl.DataSource = cityCollection; ddl.DataBind(); } } } } } } } }
aspx代码如下
[Copy to clipboard]
<%@ Page language="c#" Codebehind="TwoDropDownListInDataGrid.aspx.cs" AutoEventWireup="false" Inherits="AspxBoy.WebTest.TwoDropDownListInDataGrid" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <HTML> <HEAD> <title>TwoDropDownListInDataGrid</title> <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1"> <meta name="CODE_LANGUAGE" Content="C#"> <meta name="vs_defaultClientScript" content="JavaScript"> <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <asp:DataGrid id="dg" style="Z-INDEX: 101; LEFT: 112px; POSITION: absolute; TOP: 80px" runat="server" Width="416px" AutoGenerateColumns="False" Height="16px"> <Columns> <asp:TemplateColumn HeaderText="NO."> <ItemTemplate> <asp:Label runat="server" id="lbl_no"></asp:Label> </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn HeaderText="Province" FooterText="Province"> <ItemTemplate> <asp:DropDownList id="ddl_province" runat="server"></asp:DropDownList> </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn HeaderText="City" FooterText="City"> <ItemTemplate> <asp:DropDownList id="ddl_city" runat="server"></asp:DropDownList> </ItemTemplate> </asp:TemplateColumn> </Columns> </asp:DataGrid> </form> </body> </HTML>
另:
关于在用户控件内事件上浮(冒泡)的例子请访问下面的地址:
http://authors.aspalliance.com/hmcheung/Articles/030331/Default.aspx
在设计自定义复合控件时将控件事件上浮(冒泡)请访问:
http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cpguide/html/cpconeventbubblingcontrolsample.asp