An Extensive Examination of the DataGrid Web Control: Part 18
By Scott Mitchell
The 18th Part in a Multi-Part Series |
---|
This article is the eighteenth piece of a multi-part series on using the DataGrid Web control that will span
several months. The ASP.NET DataGrid Web control, which displays database information in an HTML table, is
highly versatile. The basics of the DataGrid were discussed in Part 1;
information on specifying display properties of the DataGrid was discussed in
Part 2. In Part 3
we examined how to associate custom events with the DataGrid.
In Part 4 we looked at how to extend
Part 3 to provide custom sorting on the results of a DataGrid. In
Part 5 we examined how to use templates to further customize
the DataGrid's appearance. Part 6 examined how to use the
DataGrid's built-in editing capabilities, while Part 7 looked at
customizing the editing interface using the EditItemTemplate. In Part 8
we looked at how to add client-side code to a ButtonColumn's client-side onclick event.
In Part 9 we examined how to enhance the DataGrid's editing
interface by having the editing interface's TextBox receive focus when the page is loaded.
In Part 10 we looked at how to (automatically) add filtering
buttons so that one can filter the data in a DataGrid. In Part 11
we examined how to create a DataGrid Web control with a column of related radio buttons.
In Part 12 we examined how to create a sortable DataGrid
that can be sorted in ascending and descending order. Part 13
examined how to sum up a DataGrid column and have the sum displayed in the footer. Part
14 looked at how to build a master/detail DataGrid. Part 15 looked at
adding paging support to a DataGrid. Part 16 examined how to create an editable
DataGrid with two data-dependent DropDownLists. Part 17 looked at building a
fully-editable DataGrid. In this eighteenth part we'll examine an alternative approach for creating a bi-directional sortable
DataGrid and see how to gussy up the DataGrid to include up and down arrows in the sorted column.
|
|
Introduction
The DataGrid Web control includes a bevy of common features, such as paging, sorting, and row-by-row editing of the DataGrid's underlying data. We've discussed how to accomplish these tasks in previous installments of the An Extensive Examination of the DataGrid Web Control article series, first looking at creating a sortable DataGrid in Part 4. Unfortunately the DataGrid's built-in sorting only allows for uni-directional sorting. That is, when creating the DataGrid you must decide on a column-by-column basis if the data will be sorted in ascending or descending order.
While it's impressive the ease with which uni-directional sorting can be added to a DataGrid, ideally we'd like to offer
bi-directional sorting. There are a couple of techniques that can be used to accomplish this end, one of which was discussed
in Part 12 of this article series. Specifically, Part 12 showed how to dynamically
adjust each DataGrid column's SortExpression
property to toggle ascending or descending sorting. One downside
of this approach, as Part 12 noted, was that you needed to hard-code in sortable column, mapping the SortExpression
to the appropriate DataGridColumns
index. This downside of this approach, then, is that it would need to be customized
for each page that you wanted to use a bi-directional sortable DataGrid.
In this 18th part of the An Extensive Examination of the DataGrid Web Control article series we'll look at an alternative approach to implementing bi-directional sorting, one that doesn't require any hard-coded mapping and therefore can easily be reused. We'll also look at a simple method that will enhance the appearance of our bi-directional sortable DataGrid, adding little up and down arrows on the column header that the grid's data is sorted by. Read on to learn more! (If you are unfamiliar with creating a sortable DataGrid, please take a moment to first read Part 4 of this article series before continuing; if you have never created a bi-directional sortable DataGrid, be sure to read Part 12 before tackling this part.)
Storing Sorting Information in the ViewState
As you know, in a sortable DataGrid each sortable column has a
SortExpression
property that is passed to the
DataGrid's SortCommand
event handler when that particular column's sort heading is clicked. Typically the
SortExpression
will contain the actual SQL syntax that you want to have injected into the ORDER BY
clause. For example, imagine that you were showing employee information in a DataGrid using BoundColumns to display the
database fields Name
, Salary
, and HireDate
. In the Salary DataGrid column you could
simply use a SortExpression
of Salary
(or Salary ASC
), which would indicate that you want to sort the column
by the Salary
field in ascending order. If you wanted to sort by salary in descending order you'd simply use
Salary DESC
as the SortExpression
.
This technique works well for creating uni-directional sortable DataGrids. For bi-directional sortable DataGrids, however,
we need to be able to dynamically add the DESC
or ASC
depending on whether or not we want to
now sort in ascending or descending order. Part 12 of this article series looked at
one technique to implement a bi-directional sortable DataGrid. Specifically, Part 12's logic checked the SortExpression
property in the SortCommand
event handler. If it ended with ASC
it changed the clicked DataGrid column's
SortExpression
, replacing the ASC
with DESC
; similarly, if the SortExpression
already ended with DESC
it was replaced with ASC
. While this approach definitely worked, one downside
was that in order to set the correct DataGrid column's SortExpression
we needed to provide a mapping from the
SortExpression
property passed in and the corresponding index in the DataGrid's Columns
collection.
With this hard-coded mapping, the code would have to be customized for each bi-directional sortable DataGrid you created.
A better approach, in my opinion, and the technique I discuss in my book ASP.NET
Data Web Controls Kick Start, is to use the ViewState to track both the column to sort by and the direction. This technique
involves maintaining two page-level properties which I usually name SortExpression
(a string) and SortAscending
(a Boolean). These two properties simply use the ViewState
StateBag as their backing store (thereby ensuring that
the values are remembered across postbacks). Then, in my SortCommand
event handler I first check to see if the
column the data is currently sorted by has already been clicked again. If so, I toggle the SortAscending
property,
thereby changing the sort direction. I finish by setting the SortExpression
property maintained in ViewState to the
SortExpression
value passed into the SortCommand
event handler.
|
The BindData()
method contains the code that grabs the appropriately-sorted data from the database and binds
it to the DataGrid. See Parts 4 or 12 for a description of the BindData()
method for a sortable DataGrid.
Improving the Appearance of the Bi-Directional Sortable DataGrid
At this point we have a working bi-directional sortable DataGrid, however there are no visual cues to indicate how the data is sorted. Many websites that offer bi-directional sortable data display a little arrow or icon next to the column that the data is sorted by. What I'd like to show is a simple method that will add a little up or down arrow next to the sorted column, depending on whether the column sorted by is sorted in ascending or descending order.
The following method, UpdateColumnHeaders(DataGrid)
, takes in as input a DataGrid and iterates through
its Columns
collection, looking for the DataGrid column by which the data is sorted. Once it finds that DataGrid
column is adds to it an image tag of either an up or down arrow, depending on if the data is sorted in ascending or
descending order. (The up and down arrows I use in the live demo can be downloaded
here: https://aspnet.4guysfromrolla.com/images/up.gif and
https://aspnet.4guysfromrolla.com/images/down.gif.) Before
adding the up or down arrow, a regular expression is used to strip out any image tag markup that might be present.
|
To use this method simply call it from the BindData()
method prior to binding the data to the DataGrid.
(See the live demo for a complete, working code example.)
Adding Up and Down Arrows Images for the ASP.NET 2.0 GridView Control |
---|
For those of you using ASP.NET 2.0, you'll be happy to know that I've written an article showing how to add these up and down arrow images for a sortable GridView. For more information, see: Extending the GridView to Include Sort Arrows. |
Conclusion (and Making this Approach Reusable)
In this article we examined an alternative approach for building a bi-directional sortable DataGrid, one that uses two ViewState-backed Page properties to keep track of the column to sort by and whether the data should be sorted in ascending or descending order. Along with this we looked at a simple, generic method that can be called to add an up or down arrow in the DataGrid column by which the data is sorted.
At the beginning of this article I mentioned my preference for using ViewState to implement a bi-directional sortable DataGrid
because it keeps the code for implementing the sort functionality loosely coupled from the data being bound to the DataGrid
(whereas the approach discussed in Part 12 had the information tightly bound). Furthermore,
the astute reader will notice that I made the UpdateColumnHeaders(DataGrid)
generic as well - that is, it
will work with any DataGrid you pass in, there's no coupling between the code and the specifics of a DataGrid.
Given this
you could easily move the sorting properties and UpdateColumnHeaders(DataGrid)
method to a custom base class.
If you have a page, then, that needs to provide a bi-directional sortable DataGrid you simply have that page inherit from the
custom base class page. With a bit of refactoring of the BindData()
method and SortCommand
event handler
you could end up with a means to create a bi-directional sortable DataGrid with just a couple lines of code. I leave this migration
to a base class and the necessary refactoring as an exercise for the interested reader. (For more information on custom base
classes be sure to read Using a Custom Base Class for your ASP.NET Page's Code-Behind Classes.)
Happy Programming!