zoukankan      html  css  js  c++  java
  • 多级Repeater嵌套,CheckBoxList赋值与读取

    最近在做电脑维修网时,需要制作一个信息订阅选择的功能,需根据数据库中的类别进行动态的生成CheckBox,以及对其赋值和读取。

    格式大致为:存在数据库中必定是按照“1,2,3,4”用逗号分隔的字符串。现在要做的核心就是根据该字符串动态的给CheckBox赋值,以及把选中的CheckBox读取为其格式。

    根据类别遍历生成CheckBox,首选用到的2个服务器组件并定是Repeater以及CheckBoxList。

    由于此处主要展示功能性代码,由此未对页面进行任何的美化处理,页面代码如下:

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Repeater嵌套CheckBoxList读取赋值Demo</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
                <ItemTemplate>
                    <div style="color: Red;">
                        <%# Eval("Name")%><asp:HiddenField ID="hidID" runat="server" Value='<%# Eval("Id")%>' />
                    </div>
                    <asp:Repeater ID="Repeater2" runat="server" OnItemDataBound="Repeater2_ItemDataBound">
                        <ItemTemplate>
                            <div style="padding: 10px 10px;">
                                <%# Container.ItemIndex+1 %><%# Eval("Name")%><br />
                                <br />
                                <asp:CheckBoxList ID="cbxName" runat="server" RepeatDirection="Horizontal" RepeatLayout="Flow">
                                </asp:CheckBoxList>
                            </div>
                        </ItemTemplate>
                    </asp:Repeater>
                </ItemTemplate>
            </asp:Repeater>
            <asp:Button ID="btnSubmit" runat="server" Text="提交" OnClick="btnSubmit_Click" />
        </div>
        </form>
    </body>
    </html>

    一共是三层嵌套,Repeater-Repeater-CheckBoxList,数据源使用数据库比较麻烦,因此作为Demo,随便虚拟一个数据源即可。如下是数据源生成代码:

    /// <summary>
    ///Entity 的摘要说明
    /// </summary>
    public class Entity
    {
        private int _id;
        /// <summary>
        /// 主键
        /// </summary>
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }
        private string _name;
        /// <summary>
        /// 名称
        /// </summary>
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        private int _parent;
    
        /// <summary>
        /// 父节点
        /// </summary>
        public int Parent
        {
            get { return _parent; }
            set { _parent = value; }
        }
        private bool _check;
        /// <summary>
        /// 选中状态
        /// </summary>
        public bool Check
        {
            get { return _check; }
            set { _check = value; }
        }
    
        private List<Entity> _list;
    
        /// <summary>
        /// 动态生成的集合
        /// </summary>
        public List<Entity> List
        {
            get { return _list; }
            set { _list = value; }
        }
        public Entity()
        {
    
        }
        /// <summary>
        /// 获取虚拟列表
        /// </summary>
        public void GetList()
        {
            List = new List<Entity>();
            int primaryKey = 1;
            for (int i = 0; i < 2; i++)
            {
                Entity obj = new Entity();
                obj.Id = primaryKey;
                obj.Name = "电脑维修网" + primaryKey;
                obj.Parent = 0;
                obj.Check = true;
                List.Add(obj);
                primaryKey++;
                for (int j = 0; j < 3; j++)
                {
                    Entity obj2 = new Entity();
                    obj2.Id = primaryKey;
                    obj2.Name = "维修类型" + primaryKey;
                    obj2.Parent = obj.Id;
                    obj2.Check = true;
                    List.Add(obj2);
                    primaryKey++;
                    for (int m = 0; m < 2; m++)
                    {
                        Entity obj3 = new Entity();
                        obj3.Id = primaryKey;
                        obj3.Name = "维修项目" + primaryKey;
                        obj3.Parent = obj2.Id;
                        obj3.Check = true;
                        List.Add(obj3);
                        primaryKey++;
                    }
                }
            }
        }
    }

    后台代码如下:

    Entity entity = new Entity();
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                //获取虚拟数据集合
                entity.GetList();
                //Repeater数据绑定
                Repeater1.DataSource = entity.List.Where(o => o.Parent == 0);
                Repeater1.DataBind();
                //给CheckBoxList赋值
                SetCheckBoxValue("3,4,6,7");
            }
        }
        /// <summary>
        /// 根据后台返回的数据列,为复选框赋值
        /// </summary>
        /// <param name="follow">以逗号分割的字符串</param>
        private void SetCheckBoxValue(string followStr)
        {
            //如果字符为空,不做任何操作
            if (string.IsNullOrEmpty(followStr))
            {
                return;
            }
            string[] follow = followStr.Split(',');
            /*
             * 首先说明下层级关系
             * 第一层为Repeater,里边继续嵌套一个Repeater,然后在嵌套的Repeater中嵌套CheckBoxList
             * Repeater-Repeater-CheckBoxList
             * 理解了嵌套关系,就很容易理解应该去如何遍历
             */
            //遍历主Repeater,然后对其子Repeater进行遍历,获取到CheckBoxList进行赋值
            for (int i = 0; i < Repeater1.Items.Count; i++)
            {
                //获取子Repeater
                Repeater rep2 = ((Repeater)Repeater1.Items[i].FindControl("Repeater2"));
                //对子Repeater进行遍历,获取到CheckBoxList进行赋值
                for (int j = 0; j < rep2.Items.Count; j++)
                {
                    //获取第二层Repeater的CheckBoxList
                    CheckBoxList cbxThreeList = ((CheckBoxList)rep2.Items[j].FindControl("cbxName"));
                    foreach (ListItem item in cbxThreeList.Items)
                    {
                        foreach (string s in follow)
                        {
                            if (item.Value == s)
                            {
                                item.Selected = true;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 获得前台选中值
        /// </summary>
        /// <returns>获取选中CheckBoxList的值,并用逗号分隔</returns>
        private string GetCheckBoxValue()
        {
            string follow = "";
            for (int i = 0; i < Repeater1.Items.Count; i++)
            {
                Repeater rep2 = ((Repeater)Repeater1.Items[i].FindControl("Repeater2"));
                for (int j = 0; j < rep2.Items.Count; j++)
                {
                    CheckBoxList cbxThreeList = ((CheckBoxList)rep2.Items[j].FindControl("cbxName"));
                    foreach (ListItem item in cbxThreeList.Items)
                    {
                        if (item.Selected == true)
                        {
                            follow += item.Value + ",";
                        }
                    }
                }
            }
            return follow.TrimEnd(',');
        }
        /// <summary>
        /// 第一层Repeater数据绑定时,进行第二层Repeater数据的绑定
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            // ItemDataBound事件触发的项包括页眉、页脚、分隔符和项。
            // 对类型进行筛选,只执行类型为项或者交替单元格中的项。
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                Repeater rep = ((Repeater)e.Item.FindControl("Repeater2"));
                //不用在前台输出隐藏标签,直接从数据源中读取数据,这样省去了前台的标签,可能有利于优化
                //Entity rowDate = e.Item.DataItem as Entity;
                //rep.DataSource = entity.List.Where(o => o.Parent == rowDate.Id);
                //在前台生成一个隐藏标签用于存值
                HiddenField hidID = ((HiddenField)e.Item.FindControl("hidID"));
                rep.DataSource = entity.List.Where(o => o.Parent == Convert.ToInt16(hidID.Value));
                rep.DataBind();
            }
    
        }
        /// <summary>
        /// 第二层Repeater数据绑定时,进行第三层CheckBoxList数据的绑定
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Repeater2_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            // This event is raised for the header, the footer, separators, and items.
            // Execute the following logic for Items and Alternating Items.
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                CheckBoxList cbxName = ((CheckBoxList)e.Item.FindControl("cbxName"));
                cbxName.DataTextField = "Name";
                cbxName.DataValueField = "Id";
                //不用在前台输出隐藏标签,直接从数据源中读取数据,这样省去了前台的标签,可能有利于优化
                Entity rowDate = e.Item.DataItem as Entity;
                cbxName.DataSource = entity.List.Where(o => o.Parent == rowDate.Id);
                cbxName.DataBind();
            }
    
        }
        /// <summary>
        /// 提交按钮执行的事件,用于显示勾选的项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            HttpContext.Current.Response.Write("<script language='javascript'>alert('选择的项:" + GetCheckBoxValue() + "');</script>");
        }

    动态生成CheckBox的核心代码都在ItemDataBound事件中,赋值和读取核心代码在方法SetCheckBoxValue与GetCheckBoxValue中。

    在Repeater1_ItemDataBound事件中有2个小技巧,那就是如何得到行数据的值,这里我在需要读取ID。

    有2种解决方案:

    第一种使用e.Item.DataItem属性,直接从绑定到Repeater的数据源中读取该行对应的数据对象,通过把其转换为具体的对象来进行数据的读取。个人比较喜欢用该方法。代码相对而言比较简洁。

    第二种直接就是在前台放一个HiddenField把ID隐藏在其中,后台通过获取该组件,然后读取该组件的值进行数据的读取,此方案使用起来比较繁琐,个人不推荐使用。

    不知是否还有其他读取方案,有兴趣的朋友可以研究研究。如果你有更好的解决方案,希望不要吝啬,能拿出来探讨探讨,以便代码的优化。毕竟学习本来就是一件分享的事情。

  • 相关阅读:
    【转】 mysql反引号的使用(防冲突)
    【百度一键分享功能】百度一键分享插件
    【WEB2.0】 网页调用QQ聊天(PC+M站)
    python : takes 0 positional arguments but 1 was given
    python : 设计模式之外观模式(Facade Pattern)
    Tosca : 扩展dll动态语言 识别点击下拉, 识别成table
    Tosca : 把 inner text 放到变量里,定义变量,使用变量
    Tosca:键盘输入字符串
    Tosca 给定义变量,取内容放到变量里
    Tosca :配置环境参数
  • 原文地址:https://www.cnblogs.com/frlmoney/p/3121473.html
Copyright © 2011-2022 走看看