Here I am explaining how to add or remove selected rows from one ASP.Net GridView Control to another in other words copying selected rows to another ASP.Net GridView Control and removing unselected rows from the another ASP.Net GridView Control
Concept
The concept behind this tutorial is to use a temporary DataTable to maintain the list selected rows or records and then use the DataTable to bind the secondary GridView.
So let us start with the tutorial initially you’ll have to download the Microsoft’s Northwind Sample Database using the link given below
Download Northwind Database
GridView Mark-up
Below is the HTML Mark-up of the ASP.Net GridViews used for this tutorial.
Primary GridView
<asp:GridView ID="gvAll" runat="server"
AutoGenerateColumns = "false" Font-Names = "Arial"
Font-Size = "11pt" AlternatingRowStyle-BackColor = "#C2D69B"
HeaderStyle-BackColor = "green" AllowPaging ="true"
OnPageIndexChanging = "OnPaging" PageSize = "10" >
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="chkAll" runat="server" onclick = "checkAll(this);"
AutoPostBack = "true" OnCheckedChanged = "CheckBox_CheckChanged"/>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chk" runat="server" onclick = "Check_Click(this)"
AutoPostBack = "true" OnCheckedChanged = "CheckBox_CheckChanged" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField = "CustomerID" HeaderText = "Customer ID"
HtmlEncode = "false" />
<asp:BoundField DataField = "ContactName" HeaderText = "Contact Name"
HtmlEncode = "false" />
<asp:BoundField DataField = "City" HeaderText = "City"
HtmlEncode = "false" />
</Columns>
<AlternatingRowStyle BackColor="#C2D69B" />
</asp:GridView>
Secondary GridView
<asp:GridView ID="gvSelected" runat="server"
AutoGenerateColumns = "false" Font-Names = "Arial"
Font-Size = "11pt" AlternatingRowStyle-BackColor = "#C2D69B"
HeaderStyle-BackColor = "green" EmptyDataText = "No Records Selected" >
<Columns>
<asp:BoundField DataField = "CustomerID" HeaderText = "Customer ID" />
<asp:BoundField DataField = "ContactName" HeaderText = "Contact Name" />
<asp:BoundField DataField = "City" HeaderText = "City" />
</Columns>
</asp:GridView>
You will notice both the GridViews are similar except that the second GridView does not have Pagination and Checkboxes
Data Binding the ASP.Net GridView control
I have used the Customers table from the Northwind Database for this example. The following function is used to databind the ASP.Net GridView control
C#
private void BindPrimaryGrid()
{
string constr = ConfigurationManager
.ConnectionStrings["conString"].ConnectionString;
string query = " select CustomerID, ContactName, City from customers";
SqlConnection con = new SqlConnection(constr);
SqlDataAdapter sda = new SqlDataAdapter(query, con);
DataTable dt = new DataTable();
sda.Fill(dt);
gvAll.DataSource = dt;
gvAll.DataBind();
}
VB.Net
Private Sub BindPrimaryGrid()
Dim constr As String = ConfigurationManager _
.ConnectionStrings("conString").ConnectionString()
Dim query As String="select CustomerID, ContactName, City from customers"
Dim con As New SqlConnection(constr)
Dim sda As New SqlDataAdapter(query, con)
Dim dt As New DataTable()
sda.Fill(dt)
gvAll.DataSource = dt
gvAll.DataBind()
End Sub
Maintaining the state of Checkboxes while paging
This is the core part of this example since its job is to keep track of the selected rows irrespective of which page it belongs and also maintain the state of the checkboxes while pagination so that user selections are not lost when he navigates from one page to another.
To facilitate this I have made use of the following two functions
1. GetData
The GetData function simply retrieves the records for which the user has checked the checkbox, adds them to a DataTable and then saves the DataTable to ViewState
C#
private void GetData()
{
DataTable dt;
if (ViewState["SelectedRecords"] != null)
dt = (DataTable)ViewState["SelectedRecords"];
else
dt = CreateDataTable();
CheckBox chkAll = (CheckBox)gvAll.HeaderRow
.Cells[0].FindControl("chkAll");
for (int i = 0; i < gvAll.Rows.Count; i++)
{
if (chkAll.Checked)
{
dt = AddRow(gvAll.Rows[i], dt);
}
else
{
CheckBox chk = (CheckBox)gvAll.Rows[i]
.Cells[0].FindControl("chk");
if (chk.Checked)
{
dt = AddRow(gvAll.Rows[i], dt);
}
else
{
dt = RemoveRow(gvAll.Rows[i], dt);
}
}
}
ViewState["SelectedRecords"] = dt;
}
VB.Net
Private Sub GetData()
Dim dt As DataTable
If ViewState("SelectedRecords") IsNot Nothing Then
dt = DirectCast(ViewState("SelectedRecords"), DataTable)
Else
dt = CreateDataTable()
End If
Dim chkAll As CheckBox = DirectCast(gvAll.HeaderRow _
.Cells(0).FindControl("chkAll"), CheckBox)
For i As Integer = 0 To gvAll.Rows.Count - 1
If chkAll.Checked Then
dt = AddRow(gvAll.Rows(i), dt)
Else
Dim chk As CheckBox = DirectCast(gvAll.Rows(i) _
.Cells(0).FindControl("chk"), CheckBox)
If chk.Checked Then
dt = AddRow(gvAll.Rows(i), dt)
Else
dt = RemoveRow(gvAll.Rows(i), dt)
End If
End If
Next
ViewState("SelectedRecords") = dt
End Sub
The GetData method makes use of the three methods
1. CreateDataTable
2. AddRow
3. RemoveRow
CreateDataTable method
This method simply creates a new object of DataTable creates its schema by adding necessary columns and then returns the DataTable object
C#
private DataTable CreateDataTable()
{
DataTable dt = new DataTable();
dt.Columns.Add("CustomerID");
dt.Columns.Add("ContactName");
dt.Columns.Add("City");
dt.AcceptChanges();
return dt;
}
VB.Net
Private Function CreateDataTable() As DataTable
Dim dt As New DataTable()
dt.Columns.Add("CustomerID")
dt.Columns.Add("ContactName")
dt.Columns.Add("City")
dt.AcceptChanges()
Return dt
End Function
The Column names are same as that of the SQL Server database.
AddRow method
The AddRow method simply adds a new row to the DataTable. It accepts the GridView row and DataTable as parameters, if it the row is not present in the DataTable it adds it and returns the updated DataTable
C#
private DataTable AddRow(GridViewRow gvRow, DataTable dt)
{
DataRow[] dr = dt.Select("CustomerID = '" + gvRow.Cells[1].Text + "'");
if (dr.Length <= 0)
{
dt.Rows.Add();
dt.Rows[dt.Rows.Count - 1]["CustomerID"] = gvRow.Cells[1].Text;
dt.Rows[dt.Rows.Count - 1]["ContactName"] = gvRow.Cells[2].Text;
dt.Rows[dt.Rows.Count - 1]["City"] = gvRow.Cells[3].Text;
dt.AcceptChanges();
}
return dt;
}
VB.Net
Private Function AddRow(ByVal gvRow As GridViewRow, ByVal dt As DataTable) As DataTable
Dim dr As DataRow() = dt.Select("CustomerID = '" _
& gvRow.Cells(1).Text & "'")
If dr.Length <= 0 Then
dt.Rows.Add()
dt.Rows(dt.Rows.Count - 1)("CustomerID") = gvRow.Cells(1).Text
dt.Rows(dt.Rows.Count - 1)("ContactName") = gvRow.Cells(2).Text
dt.Rows(dt.Rows.Count - 1)("City") = gvRow.Cells(3).Text
dt.AcceptChanges()
End If
Return dt
End Function
RemoveRow method
The RemoveRow method simply removes a row from the DataTable. It accepts the GridView row and DataTable as parameters, if it the row is present in the DataTable it removes it and returns the updated DataTable
C#
private DataTable RemoveRow(GridViewRow gvRow, DataTable dt)
{
DataRow[] dr = dt.Select("CustomerID = '" + gvRow.Cells[1].Text + "'");
if (dr.Length > 0)
{
dt.Rows.Remove(dr[0]);
dt.AcceptChanges();
}
return dt;
}
VB.Net
Private Function RemoveRow(ByVal gvRow As GridViewRow, ByVal dt As DataTable) As DataTable
Dim dr As DataRow() = dt.Select("CustomerID = '" _
& gvRow.Cells(1).Text & "'")
If dr.Length > 0 Then
dt.Rows.Remove(dr(0))
dt.AcceptChanges()
End If
Return dt
End Function
GetData method is called up in the OnPageIndexChanging event and also the OnCheckedChanged event in the following way
PageIndexChanging event
C#
protected void OnPaging(object sender, GridViewPageEventArgs e)
{
GetData();
gvAll.PageIndex = e.NewPageIndex;
BindPrimaryGrid();
SetData();
}
VB.Net
Protected Sub OnPaging(ByVal sender As Object, ByVal e As GridViewPageEventArgs)
GetData()
gvAll.PageIndex = e.NewPageIndex
BindPrimaryGrid()
SetData()
End Sub
CheckBox OnCheckChanged event
C#
protected void CheckBox_CheckChanged(object sender, EventArgs e)
{
GetData();
SetData();
BindSecondaryGrid();
}
VB.Net
Protected Sub CheckBox_CheckChanged(ByVal sender As Object, ByVal e As EventArgs)
GetData()
SetData()
BindSecondaryGrid()
End Sub
The above event is the one which will get called whenever checkbox is checked or unchecked. I will dynamically add or remove the current selected row in the primary GridView to the secondary GridView thus giving us a Shopping Cart which display the customer what all items are selected by him in the secondary GridView
The above event calls the BindSecondaryGrid function. The job of this function is to simply bind the secondary GridView with the DataTable retrieved from the ViewState
C#
private void BindSecondaryGrid()
{
DataTable dt = (DataTable)ViewState["SelectedRecords"];
gvSelected.DataSource = dt;
gvSelected.DataBind();
}
VB.Net
Private Sub BindSecondaryGrid()
Dim dt As DataTable = DirectCast(ViewState("SelectedRecords"), DataTable)
gvSelected.DataSource = dt
gvSelected.DataBind()
End Sub
Client Side Scripting
I have made use of some JavaScript methods for the Check-all checkbox functionality
Check-all checkbox functionality has already explained by me in past. You can simply refer my article
Using JavaScript with ASP.Net GridView Control
Screenshots
The screenshot below describes how the selected rows or records are displayed
Downloads
With this the article comes to an end. Hope you liked it. You can download the sample code in VB.Net and C# using the download link below
Download Code (6.66 kb)