In this article I will explain with an example, how to delete multiple rows in 
GridView control in 
ASP.Net using C# and VB.Net.
This article makes easy to delete multiple rows or records selected by the user using a single button with C# and VB.Net.
 
 
Database
I have made use of the following table Customers with the schema as follows.
![Bulk delete multiple rows in ASP.Net GridView control using CheckBoxes]() 
 
I have already inserted few records in the table.
![Bulk delete multiple rows in ASP.Net GridView control using CheckBoxes]() 
 
Note: You can download the database table SQL by clicking the download link below.
 
 
 
HTML Markup
The HTML Markup consists of:
GridView – For displaying data.
The 
GridView consists of three 
BoundField columns and one 
TemplateField column.
The 
TemplateField column consists of a 
HeaderTemplate and an 
ItemTemplate with 
CheckBox control.
CheckBoxes have been assigned with a 
JavaScript onclick event handler.
Properties
DataKeyNames – For permitting to set the names of the Column Fields, that we want to use in code but do not want to display it. Example Primary Keys, ID fields, etc.
 
PageSize – For permitting maximum number of rows to be displayed per page.
AllowPaging – For enabling paging in the 
GridView control.
 
 
Events
The 
GridView has been assigned with the following event handler i.e. 
OnPageIndexChanging.
 
HiddenField – For capturing CustomerId of the selected customer record.
Button – For deleting records.
The Button has been assigned with an OnClick and OnClientClick event handlers.
<asp:GridView ID="gvCustomers" AutoGenerateColumns="false" runat="server" DataKeyNames="CustomerId"
    AllowPaging="true" OnPageIndexChanging="OnPaging" PageSize="2">
    <Columns>
        <asp:TemplateField>
            <HeaderTemplate>
                <asp:CheckBox ID="chkAll" runat="server" onclick="CheckAll(this);" />
            </HeaderTemplate>
            <ItemTemplate>
                <asp:CheckBox ID="chkRow" runat="server" onclick="CheckRow(this)" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="CustomerId" HeaderText="Customer Id" />
        <asp:BoundField DataField="Name" HeaderText="Name" />
        <asp:BoundField DataField="Country" HeaderText="Country" />
    </Columns>
</asp:GridView>
<asp:HiddenField ID="hfCount" runat="server" Value="0" />
<br />
<asp:Button ID="btnDelete" runat="server" Text="Delete Checked Records"
    OnClientClick="returnConfirmDelete();" OnClick="Delete" />
 
 
 
Client Side Scripting
I have made use of some 
JavaScript methods for the following
2.  Confirmation before delete functionality.
 
Check-all CheckBox functionality
 
Confirmation before delete
Inside the 
ConfirmDelete function, a FOR loop is executed over all the CheckBoxes and the count of the checked 
CheckBox are get.
Finally, if the user presses OK delete operation will be performed along with appropriate message.
<script type="text/javascript">
    function ConfirmDelete() {
        var count = document.getElementById("<%= hfCount.ClientID%>").value;
        var gv = document.getElementById("<%= gvCustomers.ClientID%>");
        var chk = gv.getElementsByTagName("input");
        for (var i = 0; i < chk.length; i++) {
            if (chk[i].checked && chk[i].id.indexOf("chkAll") == -1) {
                count++;
            }
        }
        if (count == 0) {
            alert("No records to delete.");
            return false;
        }
        else {
            return confirm("Do you want to delete " + count + " records.");
        }
    };
</script>
 
 
 
Populating GridView with records from the Database
Inside the Page Load event handler, the GetData and BindGrid methods are called.
Inside the 
BindGrid method, the 
GridView is populated with the records from the 
Customers table of 
SQL Server database.
Note: The GetData method is used to retrieve the record for which the user has checked the CheckBox which will be discussed later in this article.
 
C#
protected void Page_Load(object sender, EventArgs e)
{
    if (this.IsPostBack)
    {
        this.GetData();
    }
    else
    {
        this.BindGrid();
    }
}
 
private void BindGrid()
{
    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    string sql = "SELECT CustomerId, Name, Country FROM Customers";
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlDataAdapter sda = new SqlDataAdapter(sql, con))
        {
            using (DataTable dt = new DataTable())
            {
                sda.Fill(dt);
                gvCustomers.DataSource = dt;
                gvCustomers.DataBind();
            }
        }
    }
}
 
 
VB.Net
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    If Me.IsPostBack Then
        Me.GetData()
    Else
        Me.BindGrid()
    End If
End Sub
 
Private Sub BindGrid()
    Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
    Dim sql As String = "SELECT CustomerId, Name, Country FROM Customers"
    Using con As SqlConnection = New SqlConnection(constr)
        Using sda As SqlDataAdapter = New SqlDataAdapter(sql, con)
            Using dt As DataTable = New DataTable()
                sda.Fill(dt)
                gvCustomers.DataSource = dt
                gvCustomers.DataBind()
            End Using
        End Using
    End Using
End Sub
 
 
 
Maintaining the state of CheckBoxes while paging
GetData Method
The GetData function simply retrieves the records for which the user has checked the CheckBoxes, adds them to an ArrayList and then saves the ArrayList to ViewState.
Inside the GetData method, an object of ArrayList class is created and ViewState is checked for NULL and if it is not NULL then, the value of the ViewState as ArrayList is stored in the object of ArrayList. 
Then, the 
HeaderRow CheckBox control is referenced and a FOR loop is executed over the 
GridView rows and if the 
HeaderRow CheckBox is checked, the 
CustomerId of the all records is stored in the 
ArrayList object.
If 
HeaderRow CheckBox is unchecked, then DataRow 
CheckBox is referenced and a check is performed if 
GridView row 
CheckBox is checked, the
 CustomerId for which the 
CheckBox is checked is added in the 
ArrayList object else removed if exists in the 
ArrayList.
Finally, the object of 
ArrayList class is set to the 
ViewState.
C#
private void GetData()
{
    ArrayList arr = new ArrayList();
    if (ViewState["SelectedRecords"] != null)
    {
        arr = (ArrayList)ViewState["SelectedRecords"];
    }
 
    CheckBox chkAll = (CheckBox)gvCustomers.HeaderRow.Cells[0].FindControl("chkAll");
    for (int i = 0; i < gvCustomers.Rows.Count; i++)
    {
        if (chkAll.Checked)
        {
            if (!arr.Contains(gvCustomers.DataKeys[i].Value))
            {
                arr.Add(gvCustomers.DataKeys[i].Value);
            }
        }
        else
        {
            CheckBox chk = (CheckBox)gvCustomers.Rows[i].Cells[0].FindControl("chkRow");
            if (chk.Checked)
            {
                if (!arr.Contains(gvCustomers.DataKeys[i].Value))
                {
                    arr.Add(gvCustomers.DataKeys[i].Value);
                }
            }
            else
            {
                if (arr.Contains(gvCustomers.DataKeys[i].Value))
                {
                    arr.Remove(gvCustomers.DataKeys[i].Value);
                }
            }
        }
    }
    ViewState["SelectedRecords"] = arr;
}
 
 
VB.Net
Private Sub GetData()
    Dim arr As ArrayList = New ArrayList()
    If ViewState("SelectedRecords") IsNot Nothing Then
         arr = CType(ViewState("SelectedRecords"),ArrayList)
    End If
    Dim chkAll As CheckBox = CType(gvCustomers.HeaderRow.Cells(0).FindControl("chkAll"), CheckBox)
    For i As Integer = 0 To gvCustomers.Rows.Count - 1
        If chkAll.Checked Then
            If Not arr.Contains(gvCustomers.DataKeys(i).Value) Then
                arr.Add(gvCustomers.DataKeys(i).Value)
            End If
        Else
            Dim chk As CheckBox = CType(gvCustomers.Rows(i).Cells(0).FindControl("chkRow"), CheckBox)
            If chk.Checked Then
                If Not arr.Contains(gvCustomers.DataKeys(i).Value) Then
                    arr.Add(gvCustomers.DataKeys(i).Value)
                End If
            Else
                If arr.Contains(gvCustomers.DataKeys(i).Value) Then
                    arr.Remove(gvCustomers.DataKeys(i).Value)
                End If
            End If
        End If
    Next
    ViewState("SelectedRecords") = arr
End Sub
 
 
SetData Method
The 
SetData method simply restores the saved state of the CheckBoxes from the 
ViewState to HiddenField.
Inside the SetData method, an object of ArrayList class is created and the value of the ViewState as ArrayList is stored in the object of ArrayList.
Then, the 
HeaderRow CheckBox control is referenced and a FOR loop is executed over the 
GridView rows and DataRow 
CheckBox is referenced and a check is performed if 
GridView row 
CheckBox is unchecked, then the 
CheckBox is checked if 
ArrayList contains the Checked row 
CustomerId and checked count is set.
Finally, checked CheckBoxes count is set in the HiddenField.
C#
private void SetData()
{
    int currentCount = 0;
    CheckBox chkAll = (CheckBox)gvCustomers.HeaderRow.Cells[0].FindControl("chkAll");
    chkAll.Checked =  true;
    ArrayList arr = (ArrayList)ViewState["SelectedRecords"];
    for (int i = 0; i < gvCustomers.Rows.Count; i++)
    {
        CheckBox chk = (CheckBox)gvCustomers.Rows[i].Cells[0].FindControl("chkRow");
        if (chk != null)
        {
            chk.Checked = arr.Contains(gvCustomers.DataKeys[i].Value);
            if (!chk.Checked)
            {
                 chkAll.Checked = false;
            }
            else
            {
                currentCount++;
            }
        }
    }
    hfCount.Value = (arr.Count - currentCount).ToString();
}
 
 
VB.Net
Private Sub SetData()
    Dim currentCount As Integer = 0
    Dim chkAll As CheckBox = CType(gvCustomers.HeaderRow.Cells(0).FindControl("chkAll"), CheckBox)
    chkAll.Checked =  True
    Dim arr As ArrayList = CType(ViewState("SelectedRecords"), ArrayList)
    For i As Integer = 0 To gvCustomers.Rows.Count - 1
        Dim chk As CheckBox = CType(gvCustomers.Rows(i).Cells(0).FindControl("chkRow"), CheckBox)
        If chk IsNot Nothing Then
            chk.Checked = arr.Contains(gvCustomers.DataKeys(i).Value)
            If Not chk.Checked Then
                 chkAll.Checked = False
            Else
                currentCount += 1
            End If
        End If
    Next
    hfCount.Value = (arr.Count - currentCount).ToString()
End Sub
 
 
 
Implementing Paging
Inside the 
OnPageIndexChanging event handler, the 
PageIndex property of the 
GridView is updated with the new Page Number which was clicked.
Finally, the 
GridView is populated using the 
BindGrid method which in-turn displays the new 
GridView page and 
SetData method is called.
C#
protected void OnPaging(object sender, GridViewPageEventArgs e)
{
    gvCustomers.PageIndex = e.NewPageIndex;
    gvCustomers.DataBind();
    this.BindGrid();
    this.SetData();
}
 
 
VB.Net
Protected Sub OnPaging(ByVal sender As Object, ByVal e As GridViewPageEventArgs)
    gvCustomers.PageIndex = e.NewPageIndex
    gvCustomers.DataBind()
    Me.BindGrid()
    Me.SetData()
End Sub
 
 
 
DeleteRecord Method
Inside the DeleteRecord method, the DELETE query is passed as parameter to SqlCommand class and CustomerId is added as parameter.
Then, the DELETE query is executed using ExecuteNonQuery method of SqlCommand class and the record is deleted from the database.
 
C#
private void DeleteRecord(string customerId)
{
    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    string sql = "DELETE FROM Customers WHERE CustomerId = @CustomerId";
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlCommand cmd = new SqlCommand(sql, con))
        {
            cmd.Parameters.AddWithValue("@CustomerId", customerId);
            con.Open();
            cmd.ExecuteNonQuery();
            con.Close();
        }
    }
}
 
 
VB.Net
Private Sub DeleteRecord(ByVal customerId As String)
    Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
    Dim sql As String = "DELETE FROM Customers WHERE CustomerId = @CustomerId"
    Using con As SqlConnection = New SqlConnection(constr)
        Using  cmd As SqlCommand = New SqlCommand(sql, con)
            cmd.Parameters.AddWithValue("@CustomerId", customerId)
            con.Open()
            cmd.ExecuteNonQuery()
            con.Close()
        End Using
    End Using
End Sub
 
 
 
Deleting the selected record
When Delete button is clicked, the BindGrid and SetData methods are called.
Note: The BindGrid and SetData methods are already discussed earlier in this article.
 
The 
AllowPaging property of the 
GridView is set to 
false and 
GridView is again populated.
Next, an object of 
ArrayList is created and the 
ViewState is assigned to it. 
Then, a FOR loop is executed over the 
GridView rows and if object of 
ArrayList contains 
CustomerId, 
DeleteRecord method is called and 
CustomerId of the selected record is passed as parameter and the 
CustomerId stored in the object of 
ArrayList is removed.
After that, the object of the ArrayList is set to ViewState and HiddenField value is set to zero.
Finally, the 
AllowPaging property of the 
GridView is set to 
true and 
GridView is again populated and the count of the deleted record is displayed in 
JavaScript Alert Message Box using 
RegisterStartupScript method. 
C#
protected void Delete(object sender, EventArgs e)
{
    int count = 0;
    this.BindGrid();
    this.SetData();
    gvCustomers.AllowPaging = false;
    gvCustomers.DataBind();
    ArrayList arr = (ArrayList)ViewState["SelectedRecords"];
    count = arr.Count;
    for (int i = 0; i < gvCustomers.Rows.Count; i++)
    {
        if (arr.Contains(gvCustomers.DataKeys[i].Value))
        {
            this.DeleteRecord(gvCustomers.DataKeys[i].Value.ToString());
            arr.Remove(gvCustomers.DataKeys[i].Value);
        }
    }
    ViewState["SelectedRecords"] = arr;
    hfCount.Value = "0";
    gvCustomers.AllowPaging = true;
    this.BindGrid();
    ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('" + count + " records deleted.');", true);
}
 
 
VB.Net
Protected Sub Delete(ByVal sender As Object, ByVal e As EventArgs)
    Dim count As Integer = 0
    Me.BindGrid()
    Me.SetData()
    gvCustomers.AllowPaging = False
    gvCustomers.DataBind()
    Dim arr As ArrayList = CType(ViewState("SelectedRecords"), ArrayList)
    count = arr.Count
    For i As Integer = 0 To gvCustomers.Rows.Count - 1
        If arr.Contains(gvCustomers.DataKeys(i).Value) Then
            Me.DeleteRecord(gvCustomers.DataKeys(i).Value.ToString())
            arr.Remove(gvCustomers.DataKeys(i).Value)
        End If
    Next
    ViewState("SelectedRecords") = arr
    hfCount.Value = "0"
    gvCustomers.AllowPaging = True
    Me.BindGrid()
    ClientScript.RegisterStartupScript(Me.GetType(), "alert", "alert('" & count & " records deleted.');", True)
End Sub
 
 
 
Screenshot
![Bulk delete multiple rows in ASP.Net GridView control using CheckBoxes]() 
 
 
Downloads