0

I have a table with 4 rows of state checkboxes (NJ, CA, FL, etc)

The table has an ID and a runat="server" tag, and each checkbox has an 'ID' 'Text' and 'runat="server"' tag.

I tried to make a list like below in order to use in a query but it is not getting add

List<string> query = new List<string>();
foreach (Control c in tableStates.Controls)
{
    if (c is CheckBox)
    {
        CheckBox chk = (CheckBox)c;
        if (chk.Checked)
        {
            query.Add(chk.Text);
        }
    }
}
string line = string.Join(" or ", query.ToArray());
tbTest.Text = line;

I did this before with a table but I had used form1.Controls and it worked in the foreach, but I don't want to use form1 in case there are other checkboxes other than states on the page.

Is using form1.Controls my only option or what is going on here

Here is one row of table anyway

<table runat="server" id="tableStates">
    <tr>
        <td><asp:CheckBox ID="Checkbox0" Text="AL" runat="server" /></td>
        <td><asp:CheckBox ID="Checkbox1" Text="AK" runat="server" /></td>
        <td><asp:CheckBox ID="Checkbox2" Text="AZ" runat="server" /></td>
        <td><asp:CheckBox ID="Checkbox3" Text="AR" runat="server" /></td>
        <td><asp:CheckBox ID="Checkbox4" Text="CA" runat="server" /></td>
        <td><asp:CheckBox ID="Checkbox5" Text="CO" runat="server" /></td>
        <td><asp:CheckBox ID="Checkbox6" Text="CT" runat="server" /></td>
        <td><asp:CheckBox ID="Checkbox7" Text="DE" runat="server" /></td>
        <td><asp:CheckBox ID="Checkbox8" Text="DC" runat="server" /></td>
        <td><asp:CheckBox ID="Checkbox9" Text="FL" runat="server" /></td>
        <td><asp:CheckBox ID="Checkbox10" Text="GA" runat="server" /></td>
        <td><asp:CheckBox ID="Checkbox11" Text="HI" runat="server" /></td>
        <td><asp:CheckBox ID="Checkbox12" Text="ID" runat="server" /></td>
    </tr>
</table>
Grant Winney
  • 65,241
  • 13
  • 115
  • 165
brianforan
  • 184
  • 2
  • 15
  • You need to recurse into the child controls of the table. Try this http://stackoverflow.com/a/4955836/2589202 – crthompson Aug 13 '14 at 16:59
  • never used anything other than the templates that visual studio gave me (new to c#).. do I just change _foundControls to my list name? or should I call that method? thanks for answer – brianforan Aug 13 '14 at 17:02
  • For that answer you would create a new instance (`new ControlFinder()`) and call the method on that instance. However, read through all the answers there. The extension methods look simple to implement and might be what you need. – crthompson Aug 13 '14 at 17:10
  • It'd help if I knew what recursion was I guess. One of those things that I read the definition but still don't understand. Thanks for the link though, I'm looking at the other answers now. – brianforan Aug 13 '14 at 17:24
  • 1
    Recursion is just a method that calls itself. So it looks at the child controls, then looks at their children (grandchildren) and so on down the line. What @w3hunter has done is just manually broken it down for you, it should be easier to see with what he's done. The other answer has better code however. – crthompson Aug 13 '14 at 17:30

2 Answers2

3

You need to loop through all the TableRows and TableCells within the table to get the CheckBox control.

List<string> query = new List<string>();
foreach (HtmlTableRow tr in tableStates.Controls)
{
    foreach (HtmlTableCell tc in tr.Cells)
    {
        foreach (Control c in tc.Controls)
        {
             if (c is CheckBox)
             {
                  CheckBox chk = (CheckBox)c;
                  if (chk.Checked)
                  {
                       query.Add(chk.Text);
                  }
              }
        }
    }

}
string line = string.Join(" or ", query.ToArray());
tbTest.Text = line;
PratikDotCa
  • 164
  • 11
  • is checking if c is checkbox needed? I'm getting an error on my CheckBox chk line now 'Embedded statement cannot be a declaration or labeled statement'.. this is perfect otherwise though.. edit: I took it out and it seems to be working, I'll edit again if it doesn't work – brianforan Aug 13 '14 at 17:43
  • Unable to cast object of type 'System.Web.UI.WebControls.TableRow' to type 'System.Web.UI.HtmlControls.HtmlTableRow'.. on the first foreach, not sure why – brianforan Aug 13 '14 at 17:57
  • need to import System.Web.UI.HtmlControls; – PratikDotCa Aug 13 '14 at 17:58
  • I changed my table to when you first posted the solution, could that be why?.. edit: this was why, for some reason I thought your answer was for ASP tables but now I understand why it wasn't. It's working now though, thanks – brianforan Aug 13 '14 at 18:06
  • yes.. if you are using then try using TableRow and TableCell instead. – PratikDotCa Aug 13 '14 at 18:08
3

Or try to use extension class like this:

public static class ControlExtensions
    {
        public static IEnumerable<T> GetAllControlsOfType<T>(this Control parent) where T : Control
        {
            var result = new List<T>();
            foreach (Control control in parent.Controls)
            {
                if (control is T)
                {
                    result.Add((T)control);
                }
                if (control.HasControls())
                {
                    result.AddRange(control.GetAllControlsOfType<T>());
                }
            }
            return result;
        }
    }

In this case you can utilize it like:

var checkboxes = tableStates.GetAllControlsOfType<CheckBox>();
string line = string.Join(" or ", ctrls.ToArray<CheckBox>()
                .Where<CheckBox>(x => x.Checked == true)
                .Select(x => x.Text));
apros
  • 2,848
  • 3
  • 27
  • 31