In this article I will explain with an example, how to select and delete multiple rows or records in ASP.Net GridView control using C# and VB.Net.
This article makes easy to delete multiple rows or records selected by the user using a single button in C# and VB.Net.
 
 
Database
I have made use of the following table Customers with the schema as follows.
Select and delete multiple rows in ASP.Net GridView control
 
I have already inserted few records in the table.
Select and delete multiple rows in ASP.Net GridView control
 
Note: You can download the database table SQL by clicking the download link below.
          Download SQL file
 
 
HTML Markup
The HTML Markup consists of:
GridView– For displaying data.
Columns
The GridView consists of three BoundField columns and one TemplateField column.
 
TemplateField
The TemplateField column consists of HeaderTemplate and ItemTemplate which contains ASP.Net CheckBox controls.
 
Inside the HeaderTemplate CheckBox is assigned with a JavaScript onclick event handler which calls the CheckAll JavaScript function.
And then, ItemTemplate CheckBox is assigned with a JavaScript onclick event handler which calls the CheckRow JavaScript function.
 
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.
Note: For more details on DataKeys please refer my article DataKeyNames in GridView example in ASP.Net.
 
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 an OnPageIndexChanging event handler.
 
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="return ConfirmDelete();" OnClick="Delete" />
 
 
Client Side JavaScript
The following JavaScript functions are used to check uncheck GridView CheckBoxes and display confirmation message before delete.
 
CheckRow
Inside the CheckRow function, reference is passed as a parameter and a FOR loop is executed and the header check box value is set.
Then, a check is performed if checkbox is checked then the value of checked is set as FALSE.
Finally, check value is set into the Header check box.
 
CheckAll
For more details on check and uncheck CheckBox functionality, please refer Check Uncheck all CheckBoxes in GridView using JavaScript.
 
Confirmation before delete
Inside the ConfirmDelete function, the hidden field and GridView values are set and a FOR loop is executed over all the CheckBoxes and the count of the checked CheckBox are get.
Then, the check is performed if the count is 0 then it will return FALSE.
And if it is not then the confirmation message will display in JavaScript Alert Message Box.
<script type="text/javascript">
    function CheckRow(objRef) {
        //Get the Row based on checkbox
        var row = objRef.parentNode.parentNode;
 
        //Get the reference of GridView
        var GridView = row.parentNode;
 
        //Get all input elements in Gridview
        var inputList = GridView.getElementsByTagName("input");
 
        for (var i = 0; i < inputList.length; i++) {
            //The First element is the Header Checkbox
            var headerCheckBox = inputList[0];
 
            //Based on all or none checkboxes
            //are checked check/uncheck Header Checkbox
            var checked = true;
            if (inputList[i].type == "checkbox" && inputList[i] != headerCheckBox) {
                if (!inputList[i].checked) {
                    checked = false;
                    break;
                }
            }
        }
        headerCheckBox.checked = checked;
    };
 
    function CheckAll(objRef) {
        var GridView = objRef.parentNode.parentNode.parentNode;
        var inputList = GridView.getElementsByTagName("input");
        for (var i = 0; i < inputList.length; i++) {
            var row = inputList[i].parentNode.parentNode;
            if (inputList[i].type == "checkbox" && objRef != inputList[i]) {
                if (objRef.checked) {
                    inputList[i].checked = true;
                }
                else {
                    if (row.rowIndex % 2 == 0) {
                        row.style.backgroundColor = "#C2D69B";
                    }
                    else {
                        row.style.backgroundColor = "white";
                    }
                    inputList[i].checked = false;
                }
            }
        }
    };
 
    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.");
            returnfalse;
        }
        else {
            return confirm("Do you want to delete " + count + " records.");
        }
    };
</script>
 
 
Namespaces
You will need to import following the following namespaces.
C#
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
 
VB.Net
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
 
 
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 query = "SELECT * FROM Customers";
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlDataAdapter sda = new SqlDataAdapter(query, 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 query As String = "SELECT * FROM Customers"
    Using con As SqlConnection = New SqlConnection(constr)
        Using sda As SqlDataAdapter = New SqlDataAdapter(query, 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 method retrieves the records for which the user has checked the CheckBoxes and adds them to an ArrayList and then saves the ArrayList into 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 is stored in the object of ArrayList.
Then, the HeaderRow CheckBox control is referenced and a FOR EACH loop is executed over the GridView rows and the check is performed 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");
    foreach (GridViewRow row in gvCustomers.Rows)
    {
        if (chkAll.Checked)
        {
            if (!arr.Contains(gvCustomers.DataKeys[row.RowIndex].Value))
            {
                arr.Add(gvCustomers.DataKeys[row.RowIndex].Value);
            }
        }
        else
        {
            CheckBox chk = (CheckBox)row.FindControl("chkRow");
            if (chk.Checked)
            {
                if (!arr.Contains(gvCustomers.DataKeys[row.RowIndex].Value))
                {
                    arr.Add(gvCustomers.DataKeys[row.RowIndex].Value);
                }
            }
            else
            {
                if (arr.Contains(gvCustomers.DataKeys[row.RowIndex].Value))
                {
                    arr.Remove(gvCustomers.DataKeys[row.RowIndex].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)
    ForEach row As GridViewRow In gvCustomers.Rows
        If chkAll.Checked Then
            If Not arr.Contains(gvCustomers.DataKeys(row.RowIndex).Value) Then
                arr.Add(gvCustomers.DataKeys(row.RowIndex).Value)
            End If
        Else
            Dim chk As CheckBox = CType(row.FindControl("chkRow"), CheckBox)
            If chk.Checked Then
                If Not arr.Contains(gvCustomers.DataKeys(row.RowIndex).Value) Then
                    arr.Add(gvCustomers.DataKeys(row.RowIndex).Value)
                End If
            Else
                If arr.Contains(gvCustomers.DataKeys(row.RowIndex).Value) Then
                    arr.Remove(gvCustomers.DataKeys(row.RowIndex).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 is stored in the object of ArrayList.
Then, the HeaderRow CheckBox control is referenced and a FOR EACH 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 determined.
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"];
    foreach (GridViewRow row in gvCustomers.Rows)
    {
        CheckBox chk = (CheckBox)row.FindControl("chkRow");
        if (chk != null)
        {
            chk.Checked = arr.Contains(gvCustomers.DataKeys[row.RowIndex].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 Each row As GridViewRowIn gvCustomers.Rows
        Dim chk As CheckBox = CType(row.FindControl("chkRow"), CheckBox)
        If chk IsNot Nothing Then
            chk.Checked = arr.Contains(gvCustomers.DataKeys(row.RowIndex).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;
    this.BindGrid();
    this.SetData();
}
 
VB.Net
Protected Sub OnPaging(ByVal sender As Object, ByVal e As GridViewPageEventArgs)
    gvCustomers.PageIndex = e.NewPageIndex
    Me.BindGrid()
    Me.SetData()
End Sub
 
 
DeleteRecord Method
Inside the DeleteRecord method, the DELETE query is passed as parameter to SqlCommand class and inside the SqlCommand object CustomerId is added as parameter.
Then, the DELETE query is executed using ExecuteNonQuery method of SqlCommand object and the record is deleted from the database.
Note: For more details on how to use ExecuteNonQuery function, please refer Understanding SqlCommand ExecuteNonQuery in C# and VB.Net.
C#
private void DeleteRecord(string customerId)
{
    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    string query = "DELETE FROM Customers WHERE CustomerId = @CustomerId";
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlCommand cmd = new SqlCommand(query, 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 query As String = "DELETE FROM Customers WHERE CustomerId = @CustomerId"
    Using con As SqlConnection = New SqlConnection(constr)
        Using cmd As SqlCommand = New SqlCommand(query, 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 EACH loop is executed over the GridView rows and check is performed if object of ArrayList contains CustomerId then, DeleteRecord method is called and CustomerId of the selected record is passed as parameter and the CustomerId is deleted.
After that, an 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;
    foreach (GridViewRow row in gvCustomers.Rows)
    {
        if (arr.Contains(gvCustomers.DataKeys[row.RowIndex].Value))
        {
            this.DeleteRecord(gvCustomers.DataKeys[row.RowIndex].Value.ToString());
            arr.Remove(gvCustomers.DataKeys[row.RowIndex].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 Each row As GridViewRow  In gvCustomers.Rows
        If arr.Contains(gvCustomers.DataKeys(row.RowIndex).Value) Then
            Me.DeleteRecord(gvCustomers.DataKeys(row.RowIndex).Value.ToString())
            arr.Remove(gvCustomers.DataKeys(row.RowIndex).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
Select and delete multiple rows in ASP.Net GridView control
 
 
Downloads