I wrote an article recently explaining how to create a Gridview that exports selected rows to Excel, and have received a number of queries about how to do the same with a Listview. The Listview, like the Gridview, doesn't automatically remember whether a checkbox is selected or not for each row, unless you store the value immediately in a database after each change, which is inefficient.
This example shows how to maintain checkbox state across paging and sorting within a Listview. The final steps in Gridview that exports selected rows to Excel will show you how to export these rows to Excel if you wish.

Demo | Code
Step 1 - Create a Listview
The ListView control was introduced in ASP.NET 3.5. It is an enhancement to the DataList and Repeater controls, and works by using templates to determine how records are formatted. This gives you the flexibility to display mulitple records in a horizontal or vertical grid, or in groups of 3 etc. For this example. the Listview I create will mimic the data display of a Gridview.
The basic layout of the Listview control is as follows:
<asp:ListView ID="ListView" runat="server">
<LayoutTemplate>
...
</LayoutTemplate>
<ItemTemplate>
...
</ItemTemplate>
</asp:ListView>
I am using a simple table of four data columns, with a fifth column that will display the checkboxes. I have also included a DataPager control which handles the Listview's paging.
<asp:ListView ID="Listview1" runat="server" DataKeyNames="ID" DataSourceID="dsListView">
<LayoutTemplate>
<table cellpadding="0" cellspacing="0" class="ListviewTable" width="540">
<tr>
<th style="width: 120px">
Fist Name
</th>
<th style="width: 120px">
Last Name
</th>
<th style="width: 120px">
Department
</th>
<th style="width: 120px">
Location
</th>
<th style="width: 60px; text-align: center">
</th>
</tr>
<tr id="itemPlaceholder" runat="server" />
<tr>
<td colspan="5" align="center">
Page:
<asp:DataPager ID="DataPager1" runat="server" PageSize="12">
<Fields>
<asp:NumericPagerField ButtonCount="5" />
</Fields>
</asp:DataPager>
</td>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td>
<%#Eval("FirstName") %>
</td>
<td>
<%#Eval("LastName") %>
</td>
<td>
<%#Eval("Department") %>
</td>
<td>
<%#Eval("Location") %>
</td>
<td style="text-align: center">
<asp:CheckBox ID="chkSelect" runat="server" AutoPostBack="true" />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
Step 2: Create a list variable that will store ID's of selected rows
In your code behind file, create a Private Property that will store the ID's of your selected rows:
Private ReadOnly Property IDs() As List(Of Integer)
' Create a list of ID's that are selected. ID's is the primary
' Key for this table
Get
If Me.ViewState("IDs") Is Nothing Then
Me.ViewState("IDs") = New List(Of Integer)()
End If
Return CType(Me.ViewState("IDs"), List(Of Integer))
End Get
End Property
Step 3: Create a Sub that will store the selected row ID's into your list variable
Now we create a Sub that I called AddRowstoIDList which goes through all the currently visible rows and adds the ones that have a checkbox selected to the private list variable created in step 2.
Protected Sub AddRowstoIDList()
' Loop through all the current items in the Listview
For Each lvi As ListViewDataItem In ListView1.Items
' Find the checkbox in each row
Dim chkSelect As CheckBox = CType(lvi.FindControl("chkSelect"), CheckBox)
' If the checkbox is ticked then add the corresponding ID to our private list
If (Not (chkSelect) Is Nothing) Then
' Get the ID from the datakeynames property
Dim ID As Integer =
Convert.ToInt32(Listview1.DataKeys(lvi.DisplayIndex).Value)
If (chkSelect.Checked AndAlso Not Me.IDs.Contains(ID)) Then
' Add the ID to our list
Me.IDs.Add(ID)
ElseIf (Not chkSelect.Checked AndAlso Me.IDs.Contains(ID)) Then
' Not checked - remove the ID from our list
Me.IDs.Remove(ID)
End If
End If
Next
End Sub
This sub is then called whenever the Listview is paged or sorted - we want to get the current status of the items and update our list before the Listview refreshes:
Protected Sub ListView1_PagePropertiesChanging(ByVal sender As Object,
ByVal e As System.Web.UI.WebControls.PagePropertiesChangingEventArgs)
Handles Listview1.PagePropertiesChanging
AddRowstoIDList()
End Sub
Protected Sub ListView1_Sorting(ByVal sender As Object,
ByVal e As System.Web.UI.WebControls.ListViewSortEventArgs)
Handles Listview1.Sorting
AddRowstoIDList()
End Sub
Step 4: Make sure the checkboxes are displayed correctly when the Listview is refreshed
The next step is to set the status of each checkbox correctly when the Listview is refreshed, by a sort of paging operation for example. We do this by checking each item, finding the checkbox control, and checking it if the row ID exists in our list.
Protected Sub ListView1_ItemDataBound(ByVal sender As Object,
ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs)
Handles Listview1.ItemDataBound
' Get each Listview Item on DataBound
Dim lvi As ListViewDataItem = e.Item
If (lvi.ItemType = ListViewItemType.DataItem) Then
' Find the checkbox in the current row
Dim chkSelect As CheckBox = CType(lvi.FindControl("chkSelect"), CheckBox)
' Make sure we're referencing the correct control
If (Not (chkSelect) Is Nothing) Then
' If the ID exists in our list then check the checkbox
Dim ID As Integer = Convert.ToInt32(ListView1.DataKeys(lvi.DisplayIndex).Value)
chkSelect.Checked = Me.IDs.Contains(ID)
End If
End If
End Sub
That's it! The code is very similar to the last article about the Gridview, but there are some gotcha's, particularly in how to reference items within the Gridview.
Check out the Demo or download the source code.
Bartek Marnane