Home > Mobile >  I can't seem to find the checkbox I put in a gridview for selection of rows
I can't seem to find the checkbox I put in a gridview for selection of rows

Time:11-27

I am working with a gridview which I want to select a row and then put the row in a datatable to bind with a repeater control. I am having trouble finding the selected rows using the checkbox control that I had put in the gridview. I have searched the internet and have found some information on finding controls recursively. I can find a checkbox control however the results are always a "false" checkedbox. My question, Do I need to do something when the checkbox is checked in order for the gridview to know that there was a change? The checkbox is not bound to any data in my datatable is is only used for selection purposes.

 <asp:GridView ID="GridView1" runat="server" HeaderStyle-BackColor="#191970" HeaderStyle-ForeColor="White" ShowFooter="false" RowStyle-Wrap="false"
            AlternatingRowStyle-BackColor="#80993c" AlternatingRowStyle-ForeColor="White" AutoGenerateColumns="false" GridLines="None" 
            EnableViewState="false" AllowSorting="true" ShowHeaderWhenEmpty="true" EmptyDataText="No Notaries found with the specified criteria." CssClass="GridView1" OnSorting="GridView1_Sorting1">
            <Columns>
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:CheckBox ID="notaryselect" runat="server" />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="firstname" HeaderText="First Name" SortExpression="FirstName" />
                <asp:BoundField DataField="lastname" HeaderText="Last Name" SortExpression="LastName" />
                <asp:BoundField DataField="suffix" HeaderText="Suffix" />
                <asp:BoundField DataField="city" HeaderText="City" SortExpression="City" />
                <asp:BoundField DataField="state" HeaderText="State" SortExpression="State" />
                <asp:BoundField DataField="zipcode" HeaderText="Zip Code" SortExpression="Zipcode" />
                <asp:TemplateField>
                    <HeaderTemplate>Cell Phone</HeaderTemplate>
                    <ItemTemplate>
                        <asp:HyperLink ID="hyperCellPhone" runat="server" ForeColor="Gold"
                            NavigateUrl='<%# Eval("cellphone", "tel:{0}") %>'
                            Text='<%# Eval("cellphone") %>'></asp:HyperLink>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField>
                    <HeaderTemplate>Email</HeaderTemplate>
                    <ItemTemplate>
                        <asp:HyperLink ID="hyperEmail" runat="server"
                            NavigateUrl='<%# Eval("email", "mailto:{0}") %>'
                            Text='<%# Eval("email") %>'></asp:HyperLink>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="county" HeaderText="County" SortExpression="County" />
                <asp:BoundField DataField="lat" HeaderText="Latitude" />
                <asp:BoundField DataField="long" HeaderText="Longitude" />
            </Columns>
            <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" Width="50%" />
        </asp:GridView>

Control check = FindControlRecursive(GridView1.Rows[i], "notaryselect"); 

The above line is some code just to find the checkbox. I was experimenting and found that a checkbox is returned but no matter what they all come back false which is leading me to think that since they are set to unchecked or false at the start I need to do something but I am just not sure. Everything I find on the internet shows it should work. Let me know what your thoughts are.

Here is the code for the recursive function.

 public static Control FindControlRecursive(Control Root, string Id)
{
  if (Root.ID == Id)
    return Root;
  foreach (Control c in Root.Controls)
  {
    Control fc = FindControlRecursive(c, Id);
    if (fc != null)
      return fc;
  }
  return null;
}

I found that code on this site from a similar question and wanted to see if that worked.

CodePudding user response:

You don't need any recursive function.

So, say this gv with a check box:

(it can be set to a value in the table, or not - does not matter).

So, this gv:

            runat="server" CssClass="table" AutoGenerateColumns="false"
            width="42%" DataKeyNames="ID"  >
            <Columns>
                <asp:BoundField DataField="FirstName" HeaderText="FirstName"  />
                <asp:BoundField DataField="LastName" HeaderText="LastName"    />
                <asp:BoundField DataField="HotelName" HeaderText="Hotel Name"    />
                <asp:BoundField DataField="Description" HeaderText="Description" ItemStyle-Width="270" />
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:CheckBox ID="chkActive" runat="server"
                            Checked='<%# Eval("Active") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="View">
                    <ItemTemplate>
                        <asp:Button ID="cmdView" runat="server" Text="view" 
                            CssClass="btn" OnClick="cmdView_Click" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>

Code to load is this:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadData();
    }

    void LoadData()
    {
        string strSQL = "SELECT * FROM tblHotelsA ORDER BY HotelName";
        DataTable rstData = MyRst(strSQL);
        GridView1.DataSource = rstData;
        GridView1.DataBind();
    }

    public DataTable MyRst(string strSQL)
    {
        DataTable rstData = new DataTable();
        using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
        {
            using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
            {
                cmdSQL.Connection.Open();
                rstData.Load(cmdSQL.ExecuteReader());
            }
        }
        return rstData;
    }

And we now see/get this:

enter image description here

Ok, so for the click/view button, we have this code:

    protected void cmdView_Click(object sender, EventArgs e)
    {
        Button btnView = (Button)sender;
        GridViewRow gRow = (GridViewRow)btnView.NamingContainer;

        Debug.Print("Row index click = "   gRow.RowIndex);
        int PK = (int)GridView1.DataKeys[gRow.RowIndex]["ID"];
        Debug.Print("Database PK id = "   PK);

        CheckBox ckActive = (CheckBox)gRow.FindControl("chkActive");

        if (ckActive.Checked)
            Debug.Print("check box is true");
        else
            Debug.Print("Check box is false");

    }

output:

Row index click = 2
Database PK id = 7
Check box is false

So, above is a row click sample.

But, for all rows, then this:

        foreach (GridViewRow gRow in GridView1.Rows)
        {
            CheckBox ckBox = (CheckBox)gRow.FindControl("chkActive");
            Debug.Print($"Row index = {gRow.RowIndex} Checkbox value = {ckBox.Checked.ToString()}");
        }

output:

Row index = 0 Checkbox value = True
Row index = 1 Checkbox value = False
Row index = 2 Checkbox value = False
Row index = 3 Checkbox value = True
Row index = 4 Checkbox value = False
Row index = 5 Checkbox value = True
Row index = 6 Checkbox value = True
Row index = 7 Checkbox value = True

And of course, above could also display the database PK value, and quite nice is such values don't have to be exposed client side in the GV.

eg:

  int PKID = (int)GridView1.DataKeys[gRow.RowIndex]["ID];
  • Related