How to programmatically create and use a list of checkboxes from ASP.NET?

前端 未结 7 1240
礼貌的吻别
礼貌的吻别 2021-01-19 10:37

I have a page with a table of stuff and I need to allow the user to select rows to process. I\'ve figured out how to add a column of check boxes to the table but I can\'t se

相关标签:
7条回答
  • 2021-01-19 10:41

    What I ended up doing was tagging all my ID's with a know prefix and stuffing this at the top of Form_Load:

    foreach (string v in this.Request.Form.AllKeys)
    {
        if (v.StartsWith(Prefix))
        {
            var data = v.Substring(Prefix.Length);
        }
    }
    

    everything else seems to run to late.

    0 讨论(0)
  • 2021-01-19 10:42

    First, make sure that each Checkbox has an ID and that it's got the 'runat="server"' in the tag.

    then use the FindControl() function to find it.

    For example, if you're looping through all rows in a GridView..

    foreach(GridViewRow r in Gridview1.Rows)
    {
    
        object cb = r.FindControl("MyCheckBoxId");
        if(r != null)
        {
          CheckBox chk = (CheckBox)cb;
          bool IsChecked = chk.Checked;
        }
    
    }
    
    0 讨论(0)
  • 2021-01-19 10:47

    Your post is a little vague. It would help to see how you're adding controls to the table. Is it an ASP:Table or a regular HTML table (presumably with a runat="server" attribute since you've successfully added items to it)?

    If you intend to let the user make a bunch of selections, then hit a "Submit" button, whereupon you'll process each row based on which row is checked, then you should not be handling the CheckChanged event. Otherwise, as you've noticed, you'll be causing a postback each time and it won't process any of the other checkboxes. So when you create the CheckBox do not set the eventhandler so it doesn't cause a postback.

    In your submit button's eventhandler you would loop through each table row, cell, then determine whether the cell's children control contained a checkbox.

    I would suggest not using a table. From what you're describing perhaps a GridView or DataList is a better option.


    EDIT: here's a simple example to demonstrate. You should be able to get this working in a new project to test out.

    Markup

        <form id="form1" runat="server">
        <div>
        <table id="tbl" runat="server"></table>
        <asp:Button ID="btnSubmit" runat="server" Text="Submit"
          onclick="btnSubmit_Click" />
        </div>
        </form>
    

    Code-behind

    protected void Page_Load(object sender, EventArgs e)
    {
        for (int i = 0; i < 10; i++)
        {
            var row = new HtmlTableRow();
            var cell = new HtmlTableCell();
            cell.InnerText = "Row: " + i.ToString();
            row.Cells.Add(cell);
            cell = new HtmlTableCell();
            CheckBox chk = new CheckBox() { ID = "chk" + i.ToString() };
            cell.Controls.Add(chk);
            row.Cells.Add(cell);
            tbl.Rows.Add(row);
        }
    }
    
    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        foreach (HtmlTableRow row in tbl.Rows)
        {
            foreach (HtmlTableCell cell in row.Cells)
            {
                foreach (Control c in cell.Controls)
                {
                    if (c is CheckBox)
                    {
                        // do your processing here
                        CheckBox chk = c as CheckBox;
                        if (chk.Checked)
                        {
                            Response.Write(chk.ID + " was checked <br />");
                        }
                    }
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-19 10:55

    Postback data is restored between the InitComplete event and the PreLoad event. If your checkboxes are not created until later then the checkboxes will play "catch up" with their events and the data will be loaded into the control shortly after it is created.
    If this is to late for you then you will have to do something like what you are already doing. That is you will have to access the post data before it is given to the control.
    If you can save the UniqueId of each CheckBox that you create then can directly access the post data without having to given them a special prefix. You could do this by creating a list of strings which you save the ids in as you generate them and then saving them in the view state. Of course that requires the view state to be enabled and takes up more space in the viewstate.

    foreach (string uniqueId in UniqueIds)
    {
        bool data = Convert.ToBoolean(Request.Form[uniqueId]);
        //...
    }
    
    0 讨论(0)
  • 2021-01-19 10:57

    I'm going to assume you're using a DataList but this should work with and Control that can be templated. I'm also going to assume you're using DataBinding.

    Code Front:

    <asp:DataList ID="List" OnItemDataBound="List_ItemDataBound" runat="server">
        <ItemTemplate>
            <asp:CheckBox ID="DeleteMe" runat="server"/>
            <a href="<%# DataBinder.Eval(Container, "DataItem.Url")%>" target="_blank">
                <%# DataBinder.Eval(Container, "DataItem.Title")%></a>
        </ItemTemplate>
    </asp:DataList>
    <asp:Button ID="DeleteListItem" runat="server" OnClick="DeleteListItem_Click" ></asp:Button>
    

    Code Behind:

    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
                LoadList();
        }
    
        protected void DeleteListItem_Click(object sender, EventArgs e)
        {
            foreach (DataListItem li in List.Items)
            {
                CheckBox delMe = (CheckBox)li.FindControl("DeleteMe");
    
                if (delMe != null && delMe.Checked)
                        //Do Something
                }
            }
    
            LoadList();
        }
    
        protected void LoadList()
        {
            DataTable dt = //Something...
            List.DataSource = dt;
            List.DataBind();
        }
    
        protected void List_ItemDataBound(object sender, DataListItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
            {
                string id = DataBinder.Eval(e.Item.DataItem, "ID").ToString();
                CheckBox delMe = (CheckBox)e.Item.FindControl("DeleteMe");
    
                if (delMe != null)
                    delMe.Attributes.Add("value", id);                
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-19 10:58

    Add them in an override of the CreateChildControls method of the Page. Be sure to give them an ID! This way they get added to the control tree at the correct time.

    IMHO The best way would be to use DataBound Templated Control though, i.e. something like a ListView (in .NET 3.5). then in pageload after postback traverse all items in the databound control and use item.FindControl to get at the actual checkbox.

    0 讨论(0)
提交回复
热议问题