Using ASP.NET 3.5's ListView and DataPager Controls: Sorting Data with the ListView ControlBy Scott Mitchell
When binding data to a GridView using a data source control, enabling sorting is as simple as ticking the "Enable Sorting" checkbox in the GridView's Smart Tag. Enabling sorting turns each GridView column's header into a LinkButton that, when clicked, causes a postback and re-binds the data to the GridView, sorting it by the clicked column.
Likewise, enabling sorting in the ListView is a fairly simple and straightforward process and can be accomplished without writing a line of code.
The main challenge with enabling sorting in the ListView control is that there are no pre-defined columns, like with the GridView. Therefore, we are on
the hook for defining and implementing the sorting interface. But once this is setup, the ListView can internally handle the sorting logic without the
need for us to write any additional code. Of course, in more advanced scenarios we may need to manually sort the data or programmatically specify the
sort expression used to internally sort the data. Prior to sorting, the ListView raises its
Sorting event handler, which is an ideal place
to add any additional sort-related logic. Moreover, the ListView control's sorting logic can be programmatically invoked via its
In this article we will look at how to enabling sorting in the ListView control. We will look at using the ListView's simple, baked in sorting functionality.
Following that, we will see how to programmatically invoke this sorting logic via the
Sort method as well as more advanced scenarios. Read
on to learn more!
The core concepts used to sort the ListView are the same as those used to sort the other *View Web controls: the GridView, DetailsView, and FormView. For starters, the ListView control has a
Sort(sortExpression, sortDirection)method that takes as input a string sortExpression and a
SortDirectionenumeration (which has values of
Descending). Calling the
Sortmethod raises the ListView control's
If the ListView control is bound to a data source control (like a SqlDataSource or ObjectDataSource control), the data source control is responsible for sorting the data. This sorted data is then automatically re-bound to the ListView control. In short, if you are using a data source control then sorting can be implemented in the ListView control without having to write a single line of code - it is all handled automatically by the ListView and its data source control.
If the ListView is programmatically bound to data - that is, if you have code that retrieves the data, then assigns it to the ListView's
property, and then calls the ListView's
DataBind() method - then you are responsible for re-sorting the data and re-binding it to the ListView.
To accomplish this, you will need to create an event handler for the ListView's
Sorting event, which is where you would requery the data
in the specified sorted order and re-bind it to the ListView. We will look at creating a
Sorting event handler later in this article (although
we will use it for more advanced sorting features; all of the demos here use a data source control).
So one way to kick off the ListView's sorting workflow is to call the
Sort method. Another way is to add a properly configured LinkButton,
Button, or ImageButton to the ListView's LayoutTemplate. Such a Button, when clicked, will cause a postback and initiate the sorting workflow. For this
to work, the LinkButton, Button, or ImageButton must have its
CommandName property set to
Sort and its
property set to the data field to sort by.
Implementing a Simple, Code-Free Sorting Example
To illustrate using the ListView's built-in sorting mechanism, let's look at a simple example. (This example, as well the others examined here, are available for download at the end of this article.) Let's extend the Product Listing example from the Displaying Data with the ListView article to include a sorting interface. In particular, let's add two sorting options: to sort by
ProductNameand to sort by
UnitPrice. To accomplish this, simply add two LinkButtons (or Buttons or ImageButtons) in the ListView's LayoutTemplate with appropriate
(I've left out much of the ListView's markup for brevity, focusing instead on the two sorting LinkButtons. I also omitted the AccessDataSource control that is bound to this ListView.)
Note that the two sorting LinkButtons have their
CommandName properties set to
Sort and their
properties set to the appropriate data field names. When one of these LinkButtons are clicked, a postback will occur and the ListView will automatically
Sort method passing in the LinkButton's
CommandArgument value as the sort expression. The sort direction is maintained
in an internal variable and automatically toggles if the same sort expression is sorted twice in a row. Consequently, if a visitor clicks the
"Sort by Price" link twice in a row, the first time the products will be sorted in ascending order (from cheapest to most expensive), but the
second time the sort order will reverse.
The following two screen shots show the sorting LinkButtons in action. The first screen shot shows the screen after the "Sort by Price" link has been clicked for the first time. The products are ordered in ascending order.
The second screen shot shows the results after the "Sort by Price" link has been clicked again; this time the products are ordered in descending order.
Sorting via the
The previous example looked at how to have the ListView's data sorted in response to a user clicking a LinkButton, Button, or ImageButton control. But in certain scenarios we may need to programmatically invoke the ListView's sorting workflow. For example, when a page is first loaded we may want to sort the data, or when some other user interface element on the page is engaged in some manner, we may want to resort the results. This can be accomplished by calling the ListView control's
Sortmethod, passing in the sort expression and direction.
To illustrate using this method, let's add a Button Web control to the above example that, when clicked, will sort the results by the
field. Simply add a Button Web control, set its properties, and then create a
Click event handler. In this event handler simply call the
Sort method passing in "CategoryName" as the sort expression and
SortDirection.Ascending as the sort direction.
That's all there is to it!
Clicking the Button causes a postback and calls the
Sort method, which invokes the sorting workflow. It's just as if we had added a LinkButton
to the LayoutTemplate and set its
CommandArgument properties to
Sort and "CategoryName".
Creating an Event Handler for the ListView's
In certain scenarios we may need to execute code during the ListView's sorting workflow. This can be accomplished by creating an event handler for the ListView's
Sortingevent, which is raised at the start of the sorting workflow. If the ListView's data has been programmatically bound then it is imperative that we create a
Sortingevent handler that re-sorts the data and re-binds it to the ListView. But even when we are using declarative data source controls, we may need to step into the sorting workflow and perform some custom logic.
The download available at the end of this article includes an example that "remembers" the user's five most recent sorting options and displays them
on the page as a series of LinkButtons. Clicking one of these LinkButtons re-applies the specified sort order. In creating this feature I needed to
create an event handler for the
Sorting event so that I could record the just-applied sort expression and direction.
Each of the user's past sort choices are cataloged by a
SortHistory object, which is a class I created in the website's
folder. This class has
SortDirection properties as well as read-only properties that return the
SortDirection properties as a single string and as a formatted string. The formatted string is used
for display purposes. It converts
SortDirection values of "CategoryName" and
for example, to a more human-friendly output, like: "Category (in descending order)".
I also created a
SortHistoryQueue object in the
App_Code folder, which holds a buffer of at most five
SortHistoryQueue instance is stored in Session so that the user's sort choices are remembered across postbacks, across page visits,
and are specific to a user.
In addition to using the
Sorting event handler, this demo also uses the
Sort method. As I noted earlier, the user's five most
recent sort choices are displayed as a bulleted list of LinkButtons; this is rendered using a Repeater control. Clicking a LinkButton causes a postback
and raises the Repeater's
ItemCommand event. I created an event handler for this event that applies the sort criteria used for the
clicked link by calling the ListView's
The following screen shot shows this functionality in action. The first screen shot shows the output with the five most recent sort options listed.
The second screen shot is taken right after the "Sort by Name" LinkButton has been clicked. Note the addition of the "Name (in ascending order)" LinkButton
to the bulleted list (as well as the fact that the results are sorted by
ProductName in ascending order).
In this article we looked at how to sort the data in a ListView control. Like with the GridView, DetailsView, and FormView controls, a ListView's data can be sorted without having to write a lick of code. As we saw in our first example, all that we need to do is create the sorting interface: Buttons, LinkButtons, or ImageButtons with appropriate
CommandArgumentsettings. Such button controls, when clicked, cause a postback and trigger the ListView's sorting workflow. The sorting workflow can also be invoked by explicitly calling the
Sortmethod, passing in the sort expression and direction.
While code-free sorting is definitely possible, there may be circumstances when you need to manually sort the data or perform additional sort-related
logic. In such cases, simply create an event handler for the ListView's
Sorting event (which fires at the start of the sorting workflow).
The download available at the end of this article includes an example that uses the
Sorting event handler to remember the current user's
five most recent sort choices.