asp.net/anthem 多级联动简化

刚好手头有需要用到多级联动的功能,平常写一堆代码用于数据绑定、事件绑定,实在太烦琐了,于是想办法简化一下,也顺便练练手~_~

实现比较简单,不多说,具体代码如下:

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

代码下载:点击这里

打完收工,睡觉~

你可能感兴趣的:(asp.net)