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:
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];