联动DropDownList控件

本文介绍了一个自定义的ASP.NET控件——联动下拉框,该控件实现了基于父级选择动态更新子级选项的功能,并展示了如何通过示例代码实现三级联动效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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();
        }

    }
}




此文章系转载,点这里查看原文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值