C# – How to get GridView RowIndex when checkbox is clicked

asp.netc

I have a simple gridview. Every row has some boundFields and a checkbox. The checkbox has AutoPostBack=True and fires a method (chkPlanned_OnCheckedChanged) using the OnCheckedChanged event.

     <asp:GridView ID="gvAudits" runat="server" EnablePersistedSelection="true"
            AllowSorting="True" CssClass="DDGridView"
            RowStyle-CssClass="td" HeaderStyle-CssClass="th" CellPadding="6" AutoGenerateColumns="False" DataKeyNames="AuditId" OnSorting="GridView1_Sorting" OnRowDataBound="gvAudits_RowDataBound" OnRowCommand="gvAudits_RowCommand"
            OnDataBound="OnDataBound">

            <Columns>



                <asp:BoundField DataField="AuditDate" SortExpression="AuditDate" DataFormatString="{0:dd/MM/yyyy}" HeaderText="Audit Date" ItemStyle-Width="50px" />

                <asp:TemplateField HeaderText="Division Owner" SortExpression="DivisionOwner" ItemStyle-Width="140px">
                    <ItemTemplate>
                        <div style="width: 140px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis">
                            <%# Eval("DivisionOwner") %>
                        </div>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Main Auditee" SortExpression="MainAuditee" ItemStyle-Width="140px">
                    <ItemTemplate>
                        <div style="width: 140px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis">
                            <%# Eval("MainAuditee") %>
                        </div>
                    </ItemTemplate>
                </asp:TemplateField>

                <asp:BoundField DataField="TotalFindings" SortExpression="TotalFindings" HtmlEncode="False" HeaderText="Total <br />Findings " ItemStyle-Width="25px">
                    <ItemStyle HorizontalAlign="Right"></ItemStyle>
                </asp:BoundField>

                <asp:BoundField DataField="NoMajorFindings" SortExpression="NoMajorFindings" HtmlEncode="False" HeaderText="Major <br />Findings " ItemStyle-Width="25px">
                    <ItemStyle HorizontalAlign="Right"></ItemStyle>
                </asp:BoundField>




                <asp:TemplateField HeaderText="Potential" SortExpression="Planned">
                    <ItemTemplate>
                        <asp:CheckBox runat="server" ID="chkPlanned" Checked='<%# Convert.ToBoolean(Eval("Planned"))%>' AutoPostBack="True"   OnCheckedChanged="chkPlanned_OnCheckedChanged" />
                    </ItemTemplate>
                    <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="50px" />
                    <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="50px" />
                </asp:TemplateField>


                <asp:BoundField DataField="AuditId" HeaderText="AuditId" SortExpression="AuditId"
                    ReadOnly="True" Visible="False">
                    <HeaderStyle Width="50px" />
                </asp:BoundField>
                <asp:TemplateField HeaderText="Delete">
                    <ItemTemplate>
                        &nbsp;<asp:LinkButton runat="server" CommandName="Delete" Text="Delete"
                            OnClientClick='return confirm("Are you sure you want to delete this item?");' CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>'><i class="fa fa-remove"></i></asp:LinkButton>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>


            <EmptyDataTemplate>
                There are currently no items in this table.
            </EmptyDataTemplate>
        </asp:GridView>

This method in the C# code behind then gets the rowIndex using the following logic:

protected void chkPlanned_OnCheckedChanged(object sender, EventArgs e)
    {
  CheckBox chk = (CheckBox) sender;
  GridViewRow gr = (GridViewRow) chk.Parent.Parent;
  var dataKey = gvAudits.DataKeys[gr.RowIndex];
}

Everything was working perfect then I needed to add in a grouped column header which I did programmatically as follows:

    protected void OnDataBound(object sender, EventArgs e)
    {
        GridViewRow row = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal);
        TableHeaderCell cell = new TableHeaderCell();
        cell.Text = "";
        cell.ColumnSpan = 5;
        row.Controls.Add(cell);

        cell = new TableHeaderCell();
        cell.ColumnSpan = 3;
        cell.Text = "Finding Status";
        row.Controls.Add(cell);

        cell = new TableHeaderCell();
        cell.ColumnSpan = 3;
        cell.Text = "Finding Type";
        row.Controls.Add(cell);


        cell = new TableHeaderCell();
        cell.ColumnSpan = 3;
        cell.Text = "";
        row.Controls.Add(cell);

        row.BackColor = ColorTranslator.FromHtml("#3AC0F2");
        gvAudits.HeaderRow.Parent.Controls.AddAt(0, row);
    }

The problem is, now when I click a checkbox after the grouping header was added, I cannot get the RowIndex from the codebehind any longer. gr.RowIndex always returns 0. Any ideas why this is?

Perhaps there is a way to add a grouping to the gridview header in ASPX rather than in code behind and this will then fix the problem?
Header with groupings added

Best Answer

Use below code, Hope it will solve your problem

public void Chacked_Changed(object sender, EventArgs e)
{
GridViewRow Row = ((GridViewRow)((Control)sender).Parent.Parent);
string id = grd1.DataKeys[Row.RowIndex].Value.ToString();
string cellvalue = Row.Cells[1].Text;
}

OR use

 CheckBox chk = (CheckBox)sender; 
 GridViewRow gvr = (GridViewRow)chk.NamingContainer;
 string id = GridView1.Rows[gvr.RowIndex].Value.ToString();
 string cellvalue = GridView1.Rows[gvr.RowIndex].Cells[1].Text;