如何在不丢失复选框信息的情况下向转发器添加新行

时间:2022-09-17 11:11:57

I have a simple Repeater that contains a checkbox and a Full name per each row. In addition, I have an "Add Name" button that adds a new full name to the database.

我有一个简单的Repeater,每行包含一个复选框和一个全名。另外,我有一个“添加名称”按钮,为数据库添加一个新的全名。

Supposingly user checks a few checkboxes and decides to add another name, I would like to be able to add a new name to the repeater without losing the information in the checkboxes that have been already checked.

假设用户检查了几个复选框并决定添加另一个名称,我希望能够在转发器中添加新名称而不会丢失已经检查过的复选框中的信息。

I understand some javascript code might do the trick the question is how to approach it? What do I do?

我理解一些javascript代码可能会成功的问题是如何处理它?我该怎么办?

thanks in advance

提前致谢

p.s. I'll be glad to hear any advice, not olny regarding js.

附:我会很高兴听到任何建议,而不是关于js的任何建议。

2 个解决方案

#1


1  

Here is quick solution, not very pretty but get the job done. Hope it will give you some new ideas

这是快速解决方案,不是很漂亮,但完成工作。希望它会给你一些新的想法


Default.aspx.cs

Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace RepeaterCheckbox
{
    public partial class _Default : System.Web.UI.Page
    {
        [Serializable]
        public class Person
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }

        List<Person> personsFromDatabase
        {
            get { return (List<Person>)ViewState["persons"]; }
            set { ViewState["persons"] = value; }
        }

        //here we will store our person selection state
        Dictionary<int,bool> personSelectionState
        {
            get { return (Dictionary<int, bool>)ViewState["data"]; }
            set { ViewState["data"] = value; }
        }

        protected override void OnLoad(EventArgs e)
        {
            if (!IsPostBack)
            {
                #region Test data
                personsFromDatabase = new List<Person>{
                    new Person { Id = 1, Name = "Paul", },
                    new Person { Id = 2, Name = "Tom", },
                };
                #endregion

                Bind(false);
            }
            base.OnLoad(e);
        }

        void Bind(bool isPostback)
        {
            if (!isPostback)
            {
                //initialize person selection mapping
                personSelectionState = new Dictionary<int, bool>();
                foreach (Person person in personsFromDatabase)
                personSelectionState.Add(person.Id, false);
            }

            //map persons to anonymous type that will help us define necessary values
            rpPersons.DataSource = personsFromDatabase.Select(x => new
            {
                Id = x.Id,
                Name = x.Name,
                //get stored selection state for person
                Selected = personSelectionState[x.Id],
            });
            rpPersons.DataBind();
        }

        protected void btnAddPerson_Click(object sender, EventArgs e)
        {
            //update selection states
            UpdateSelectionStatuses();

            if (!String.IsNullOrEmpty(txbName.Text))
            {
                //add new person
                personsFromDatabase.Add(new Person
                    {
                        Id = personsFromDatabase.Count +1,
                        Name = txbName.Text,
                    });

                //add status mapping for new person so there is no error on postback binding
                personSelectionState.Add(personsFromDatabase.Count, false);

                //Refresh data on page, to see new person
                Bind(true);
            }
        }

        void UpdateSelectionStatuses()
        {
            //loop through all items
            for (int i = 0; i < rpPersons.Items.Count; ++i)
            {
                RepeaterItem repeaterItem = rpPersons.Items[i];

                //find checkbox for item
                var checkbox = (CheckBox)repeaterItem.FindControl("chbSelected");
                if (checkbox != null)
                {
                    //get our custom attribute
                    int id = int.Parse(checkbox.Attributes["personId"]);

                    //update stored checkbox status
                    personSelectionState[id] = checkbox.Checked;
                }
            }
        }

        protected void rpPersons_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                var item = e.Item.DataItem;

                var checkbox = (CheckBox)e.Item.FindControl("chbSelected");
                if (item != null && checkbox != null)
                {
                    //get person id from our helper anonymous type
                    System.Reflection.PropertyInfo[] anonymousTypeProperties = item.GetType().GetProperties();
                    int id = (int)anonymousTypeProperties.Where(x => x.Name == "Id").FirstOrDefault().GetValue(item, null);

                    //set custom attribute on checkbox to map checkbox with person
                    checkbox.Attributes["personId"] = id.ToString();
                }
            }
        }
    }
}

Default.aspx

Default.aspx的

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="RepeaterCheckbox._Default" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Repeater runat="server" ID="rpPersons" OnItemDataBound="rpPersons_ItemDataBound" >
                <ItemTemplate>
                    <p>
                        <asp:CheckBox ID="chbSelected" runat="server" AutoPostBack="false" Checked='<%# DataBinder.Eval(Container.DataItem, "Selected") %>' />
                        <asp:Label ID="lblName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' />
                    </p>
                </ItemTemplate>
            </asp:Repeater>
            <div>
                <asp:TextBox ID="txbName" runat="server" />
                <asp:Button ID="btnAddPerson" runat="server" Text="Add person" OnClick="btnAddPerson_Click" />
            </div>
        </div>
    </form>
</body>
</html>

#2


1  

It depends how do you approach it. Are you using the asp.net repeater in an Ajax update panel? If is the case you can save check box value at each click event this way when you add a new item the control will be rebinded with the updated values.

这取决于你如何接近它。您是否在Ajax更新面板中使用asp.net转发器?如果是这种情况,您可以在每次单击事件时以这种方式保存复选框值,当您添加新项目时,控件将使用更新的值进行重新绑定。

If you like to use client side javascript thie post could help you: How to add rows to a repeater in client side

如果你想使用客户端javascript帖子可以帮助你:如何在客户端向转发器添加行

#1


1  

Here is quick solution, not very pretty but get the job done. Hope it will give you some new ideas

这是快速解决方案,不是很漂亮,但完成工作。希望它会给你一些新的想法


Default.aspx.cs

Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace RepeaterCheckbox
{
    public partial class _Default : System.Web.UI.Page
    {
        [Serializable]
        public class Person
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }

        List<Person> personsFromDatabase
        {
            get { return (List<Person>)ViewState["persons"]; }
            set { ViewState["persons"] = value; }
        }

        //here we will store our person selection state
        Dictionary<int,bool> personSelectionState
        {
            get { return (Dictionary<int, bool>)ViewState["data"]; }
            set { ViewState["data"] = value; }
        }

        protected override void OnLoad(EventArgs e)
        {
            if (!IsPostBack)
            {
                #region Test data
                personsFromDatabase = new List<Person>{
                    new Person { Id = 1, Name = "Paul", },
                    new Person { Id = 2, Name = "Tom", },
                };
                #endregion

                Bind(false);
            }
            base.OnLoad(e);
        }

        void Bind(bool isPostback)
        {
            if (!isPostback)
            {
                //initialize person selection mapping
                personSelectionState = new Dictionary<int, bool>();
                foreach (Person person in personsFromDatabase)
                personSelectionState.Add(person.Id, false);
            }

            //map persons to anonymous type that will help us define necessary values
            rpPersons.DataSource = personsFromDatabase.Select(x => new
            {
                Id = x.Id,
                Name = x.Name,
                //get stored selection state for person
                Selected = personSelectionState[x.Id],
            });
            rpPersons.DataBind();
        }

        protected void btnAddPerson_Click(object sender, EventArgs e)
        {
            //update selection states
            UpdateSelectionStatuses();

            if (!String.IsNullOrEmpty(txbName.Text))
            {
                //add new person
                personsFromDatabase.Add(new Person
                    {
                        Id = personsFromDatabase.Count +1,
                        Name = txbName.Text,
                    });

                //add status mapping for new person so there is no error on postback binding
                personSelectionState.Add(personsFromDatabase.Count, false);

                //Refresh data on page, to see new person
                Bind(true);
            }
        }

        void UpdateSelectionStatuses()
        {
            //loop through all items
            for (int i = 0; i < rpPersons.Items.Count; ++i)
            {
                RepeaterItem repeaterItem = rpPersons.Items[i];

                //find checkbox for item
                var checkbox = (CheckBox)repeaterItem.FindControl("chbSelected");
                if (checkbox != null)
                {
                    //get our custom attribute
                    int id = int.Parse(checkbox.Attributes["personId"]);

                    //update stored checkbox status
                    personSelectionState[id] = checkbox.Checked;
                }
            }
        }

        protected void rpPersons_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                var item = e.Item.DataItem;

                var checkbox = (CheckBox)e.Item.FindControl("chbSelected");
                if (item != null && checkbox != null)
                {
                    //get person id from our helper anonymous type
                    System.Reflection.PropertyInfo[] anonymousTypeProperties = item.GetType().GetProperties();
                    int id = (int)anonymousTypeProperties.Where(x => x.Name == "Id").FirstOrDefault().GetValue(item, null);

                    //set custom attribute on checkbox to map checkbox with person
                    checkbox.Attributes["personId"] = id.ToString();
                }
            }
        }
    }
}

Default.aspx

Default.aspx的

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="RepeaterCheckbox._Default" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Repeater runat="server" ID="rpPersons" OnItemDataBound="rpPersons_ItemDataBound" >
                <ItemTemplate>
                    <p>
                        <asp:CheckBox ID="chbSelected" runat="server" AutoPostBack="false" Checked='<%# DataBinder.Eval(Container.DataItem, "Selected") %>' />
                        <asp:Label ID="lblName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' />
                    </p>
                </ItemTemplate>
            </asp:Repeater>
            <div>
                <asp:TextBox ID="txbName" runat="server" />
                <asp:Button ID="btnAddPerson" runat="server" Text="Add person" OnClick="btnAddPerson_Click" />
            </div>
        </div>
    </form>
</body>
</html>

#2


1  

It depends how do you approach it. Are you using the asp.net repeater in an Ajax update panel? If is the case you can save check box value at each click event this way when you add a new item the control will be rebinded with the updated values.

这取决于你如何接近它。您是否在Ajax更新面板中使用asp.net转发器?如果是这种情况,您可以在每次单击事件时以这种方式保存复选框值,当您添加新项目时,控件将使用更新的值进行重新绑定。

If you like to use client side javascript thie post could help you: How to add rows to a repeater in client side

如果你想使用客户端javascript帖子可以帮助你:如何在客户端向转发器添加行