Multiple Column Sorting and Paging in a DataGrid
 
Published: 20 Apr 2005
Unedited - Community Contributed
Abstract
This article demonstrates a comprehensive solution for implementing multiple column sorting in an ASP.NET DataGrid, with support for paging.
by souri challa
Feedback
Average Rating: 
Views (Total / Last 10 Days): 55263/ 62

Introduction

 [ Download Code ]

Much has been written about the sorting and paging capabilities of the ASP.NET DataGrid. This article examines bringing together all the aspects of sorting on multiple columns and paging while presenting an easier, intuitive interface.

The goals of the code sample that accompanies this article are to:

  • present an easier way to sort on a combination of DataGrid columns in ascending or descending order;
  • indicate visually the sort direction and sequence number; and 
  • remember the selected sort expression between DataGrid pages.

Before we delve into the code take a look at the screenshot of the DataGrid below.

 


Figure 1: The DataGrid in its final form

 

As you can see, the sort direction is displayed by way of a simple image next to the sorted column in the DataGrid header. The number next to the image represents the sort sequence number for that column. The user can click on any sort-enabled column multiple times to toggle between one of three possible states: ascending, descending, or no sort order. The code sample that accompanies this article also writes the sort expression to the browser's status bar.

DataGrid Declaration and Data Source

 [ Download Code ]

Now let us examine the code in a little detail. The declarative portion of the DataGrid is shown below. Setting the AllowSorting and AllowPaging attributes to true enables the sorting and paging functionality of the DataGrid.

<asp:datagrid id="dgEmployee" runat="server" AllowSorting="True"
AllowPaging="True" AutoGenerateColumns="False"Width="100%"
PageSize="20" Font-Size="10" Font-Name="verdana">
  <AlternatingItemStyle BackColor="#CCCC99"></AlternatingItemStyle>
  <HeaderStyle Font-Bold="True" BackColor="#FFCC00"></HeaderStyle>
     <Columns>
<asp:BoundColumn DataField="FirstName" SortExpression="FirstName"
HeaderText="First Name"></asp:BoundColumn>
<asp:BoundColumn DataField="LastName"  SortExpression="LastName"
HeaderText="Last Name"></asp:BoundColumn>
<asp:BoundColumn DataField="HireDate"  SortExpression="HireDate"
HeaderText="Hire Date"></asp:BoundColumn>
<asp:BoundColumn DataField="Job" SortExpression="Job"
HeaderText="Job Description"></asp:BoundColumn>
<asp:BoundColumn DataField="Publisher"  SortExpression="Publisher"
HeaderText="Publisher"></asp:BoundColumn>
<asp:BoundColumn DataField="City" SortExpression="City"
HeaderText="City"></asp:BoundColumn>
<asp:BoundColumn DataField="State" SortExpression="State"
HeaderText="State"></asp:BoundColumn>
<asp:BoundColumn DataField="Country"
HeaderText="Country"></asp:BoundColumn>
    </Columns>
 <PagerStyle PageButtonCount="20" Mode="NumericPages"></PagerStyle>
</asp:datagrid>
Listing 1

To keep the demonstration simple, the DataGrid is bound to an XML data source, as shown below.

<?xml version="1.0" encoding="utf-8" ?>
<EMPLOYEE>
      <EmpData FirstName="Paolo" LastName="Accorti" HireDate="1992-08-27"
Job="Sales Representative" Publisher="Binnet Hardley" City="Washington"
State="DC" Country="USA" />
      <EmpData FirstName="Pedro" LastName="Afonso" HireDate="1990-12-24"
Job="Designer" Publisher="Algodata Infosystems" City="Berkeley"
State="CA" Country="USA" />
      <EmpData FirstName="Victoria" LastName="Ashworth" HireDate="1990-09-13"
Job="Managing Editor" Publisher="Binnet Hardley" City="Washington"
State="DC" Country="USA" />
</EMPLOYEE>
Listing 2

When a sort expression of a bound column is set, the DataGrid renders the header of the column as a link button. Upon clicking such a link, the DataGrid’s SortCommand event fires and supplies the sort expression as part of the event argument.

Sorting the DataGrid

 [ Download Code ]

The code for the SortCommand event handler is shown below. In a nutshell, the event handler determines a combined sort expression, sets up a DataView on the current data source with that sort expression, and binds the DataGrid to the DataView.

/// <summary>
///  Datagrid Sort Event Handler -> Determine a combined sort expression and apply.
/// </summary>
private void dgEmployee_SortCommand(object source,
System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
{
  DisplaySortedData(GetSortExpression(dgEmployee,e));
}
/// <summary>
///  Apply the Sort Expression to the retrieved data and bind to datagrid
/// </summary>
private void DisplaySortedData(string sortExpression)
      {
            sortExpression = sortExpression.TrimEnd(",".ToCharArray());
            DataSet dsEmployees = new DataSet();
            dsProjects.ReadXml(Server.MapPath("Employee.xml"));
                  
            DataView dvEmployee = new DataView(dsEmployees.Tables[0]);
            dvEmployee.Sort =  sortExpression;
            dgEmployee.DataSource = dvEmployee;
            dgEmployee.DataBind();
      }

Listing 3

The key to implementing the multi-column sorting is to remember the previously clicked sort columns, and to establish the new sort criteria whenever a sort column header is clicked.

In this example the sort expression is persisted between requests in a custom DataGrid attribute named SortExpression. When the page is rendered to the browser this attribute becomes the attribute of the TABLE HTML element and is simply ignored by the browsers.

Another way of persisting the sort expression would be to keep it in a ViewState variable. This method is recommended if the DataGrid itself is not kept in ViewState due to large amounts of data.

Manipulating the Sort Expression

 [ Download Code ]

The GetSortExpression method shown below implements the functionality to evaluate a new sort expression each time a sortable column header is clicked. It starts by examining the custom SortExpression attribute of the DataGrid to see if a previous sort expression exists. If the current sort column exists within this expression, then its sort order is toggled appropriately or the sort column is removed from the sort expression. Otherwise, the sort column is added to the SortExpression attribute.

private string GetSortExpression(DataGrid dg,DataGridSortCommandEventArgs e)
{
      string[] sortColumns = null;
      string sortAttribute = dg.Attributes["SortExpression"];
      //Check to See if we have an existing Sort Order already in the Grid.     
      //If so get the Sort Columns into an array
            if ( sortAttribute != String.Empty)
            {
                  sortColumns = sortAttribute.Split(",".ToCharArray());
            }
      //if User clicked on the columns in the existing sort sequence.
      //Toggle the sort order or remove the column from sort appropriately
            if (sortAttribute.IndexOf(e.SortExpression) > 0 ||
            sortAttribute.StartsWith(e.SortExpression))
            sortAttribute= ModifySortExpression(sortColumns,e.SortExpression);
            else 
            sortAttribute += e.SortExpression+" ASC,";
            dg.Attributes["SortExpression"] = sortAttribute;                 
return sortAttribute;
}
 
private string ModifySortExpression(string[] sortColumns,string sortExpression)
{
            string  ascSortExpression = String.Concat(sortExpression," ASC");
            string  descSortExpression = String.Concat(sortExpression," DESC");    
for (int i=0; i< sortColumns.Length; i++)
      {    
 
            if (ascSortExpression.Equals(sortColumns[i]))
                  {
                        sortColumns[i] = descSortExpression;
                  }
                             
            else if (descSortExpression.Equals(sortColumns[i]))
                  { Array.Clear(sortColumns,i,1);
                  }
            }
             
return
String.Join(",",sortColumns).Replace(",,",",").TrimStart(",".ToCharArray());
       
}
Listing 4

The paging event handler calls upon the same method to display the data in sorted order, after setting up the current page index.

/// <summary>
///  Datagrid Page Changed Event Handler -> Apply the Currently Selected sort expression.
/// </summary>
private void dgEmployee_PageIndexChanged(object source,
System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
{
      dgEmployee.CurrentPageIndex = e.NewPageIndex;
      DisplaySortedData(dgEmployee.Attributes["SortExpression"]);
}
Listing 5
Displaying Sort Direction and Sequence

 [ Download Code ]

One more important aspect of this example is to display the current sorting order in the DataGrid header in a manner that is easy to recognize visually. This is accomplished by inserting an image and number next to the sorted column.

This is implemented in the ItemDataBound event handler of the DataGrid when binding the header item.

private void dgEmployee_ItemDataBound(object sender,
System.Web.UI.WebControls.DataGridItemEventArgs e)
{
  if (e.Item.ItemType == ListItemType.Header)
    {
if (dgEmployee.Attributes["SortExpression"] != String.Empty)
DisplaySortOrderImages(dgEmployee.Attributes["SortExpression"] ,e.Item);
    }       
}
Listing 6

The method DisplaySortOrderImages loops through the cells of the header item. If any of the cells contain a link button, it then looks up its command argument (which is same as that columns sort expression) within the DataGrid’s SortExpression attribute and inserts an image and a literal (for the sequence number) next to the cell.

private void DisplaySortOrderImages(string sortExpression,DataGridItem dgItem)
{       
  string[] sortColumns = sortExpression.Split(",".ToCharArray());
 for (int i=0; i< dgItem.Cells.Count; i++)
 { 
if(dgItem.Cells[i].Controls.Count > 0 && dgItem.Cells[i].Controls[0] is LinkButton)
{
     string sortOrder;
     int sortOrderNo;
     string column = ((LinkButton)dgItem.Cells[i].Controls[0]).CommandArgument;
                    
     SearchSortExpression(sortColumns,column,out sortOrder,out sortOrderNo);
       if (sortOrderNo > 0)
       {
             if (sortOrder.Equals("ASC"))
            {
            Image imgUp = new Image();
            imgUp.ImageUrl = "~/images/sortascending.gif";
            dgItem.Cells[i].Controls.Add(imgUp);
            Literal litOrder = new Literal();
            litOrder.Text = sortOrderNo.ToString();
            dgItem.Cells[i].Controls.Add(litOrder);
            }
            else if (sortOrder.Equals("DESC"))
            {
            Image imgDown = new Image();
            imgDown.ImageUrl = "~/images/sortdescending.gif";
            dgItem.Cells[i].Controls.Add(imgDown);
            Literal litOrder = new Literal();
            litOrder.Text = sortOrderNo.ToString();
            dgItem.Cells[i].Controls.Add(litOrder);
            }
}
 
         }
}
             
 } 





private void SearchSortExpression(string[] sortColumns,string sortColumn,
out string sortOrder,out int sortOrderNo)
{ 
      sortOrder = "";
     sortOrderNo = -1;
for (int i=0; i< sortColumns.Length; i++)
      {
             if (sortColumns[i].StartsWith(sortColumn))
            {
                  sortOrderNo = i+1;
                  sortOrder = sortColumns[i].Substring(sortColumn.Length).Trim();
}
       }
}
Listing 7


Conclusion

To summarize, we've taken advantage of the DataView's sorting capabilities to implement multi-column sorting on the DataGrid. Full source code is included in the downloadable sample. It also shows how to write the sort expression to the browser status bar by registering a client-side Javascript function. Enjoy, and be sure to let me know if you find this article applicable to your project scenario.



User Comments

Title: sddf   
Name: dfs
Date: 2012-10-18 7:05:55 AM
Comment:
dfsdfsdf
Title: ok   
Name: ok
Date: 2012-07-12 9:00:11 AM
Comment:
hhi
Title: nfl jerseys cheap   
Name: NIKE NFL jerseys
Date: 2012-07-02 10:11:50 AM
Comment:
http://www.jersey2shop.com
http://www.cheapjersey2store.com
http://www.jerseycaptain.com
http://www.yourjerseyhome.com
We are professional jerseys manufacturer from china,wholesal.cheap nike nfl jerseys, mlb jerseys, nhl jerseys,nba jerseys and shoes
Cheap NFL,NBA,MLB,NHL
,heap jerseys,2012 nike nfl Jerseys,nba jersey and shorts,oklahoma city thunder jersey,official jeremy lin new york knicks jersey,NFL Jerseys Wholesale,blake griffin jersey blue,NFL jerseys For Sale online.All Our Jerseys Are Sewn On and Directly From Chinese Jerseys Factory
,Wholesale cheap jerseys,Cheap mlb jerseys,]Nike NFL Jerseys,Cheap China Wholesae,Wholesale jerseys From China,2012 nike nfl Jerseys,Jerseys From China,,2012 nike nfl Jerseys,Revolution 30 nba jerseys,jersey of nba chicago bulls direk rose ,nfl jerseys,green bay packers jerseys wholesale,Buffalo Bills nike nfl jerseys sale,good supplier soccer jerseys,cool base mlb jerseys,Revolution 30 nba jerseys,2012 stanley cup nhl jersey,
We are professional jerseys manufacturer from china,wholesal.cheap nike nfl jerseys, mlb jerseys, nhl jerseys,nba jerseys and shoes. www.yourjerseyhome.com
Title: Date Sorting   
Name: saka
Date: 2008-09-29 8:11:22 AM
Comment:
When I sort a list by date. But it not sort date wise
It sort string wise.

How to sort it in datewise?

dtGridSort = policyFeeCollection.GetDataTable
dataviewGrid = dtGridSort.DefaultView
dataviewGrid.Sort = "EnteredDate Asc"
grdPolicyFee.DataSource = dataviewGrid
grdPolicyFee.DataBind()
Title: Multiple Column Sorting and Paging in a DataGrid   
Name: Lakshitha
Date: 2008-09-02 12:09:20 AM
Comment:
please let me know how do above "Multiple Column Sorting and Paging in a DataGrid" using ASP.NET 2005..... becoze asp.net2005 not there datagrid so how can do this using asp.net 2005??
Title: Excellent   
Name: Murugan
Date: 2008-05-20 12:07:40 PM
Comment:
The code was very useful.
Question: I'm writing a custom gridview and the grid does not keep the last sorting order for the next page.
Did you ever think about this? any ideas?
Thanks, Murugan
Title: hello   
Name: salman
Date: 2007-08-06 2:30:57 AM
Comment:
very good
Title: Gr8 !!!!!   
Name: Bipul
Date: 2007-05-31 6:58:17 AM
Comment:
Too good.. My requirement was not exactly like that but after some modification I have fullfilled that..

Really excellent article.....

Thanks,
Bipul
Title: Multi-Sorting code   
Name: Pri
Date: 2007-04-09 3:33:46 PM
Comment:
The code was real useful and saved lot of time. I just have one question. When I try to sort on the first column, it actually sorts on first and second column together. It look sas if both the columns are bound together. Can you please tell me how to fix this issue. Thanks again for the code.
Title: Than You   
Name: Santosh
Date: 2007-02-21 8:18:45 AM
Comment:
Hi,
This is Santosh,Nice Article & it is useful 2 me.. Thank U..
Title: Excellent   
Name: Nishant
Date: 2007-02-06 10:54:27 PM
Comment:
I appreciate your way of explaining sorting,paging in a very simple manner. It is very useful
Title: It is a Excellent articl   
Name: M.Murugesan
Date: 2006-08-21 10:04:04 AM
Comment:
it is a very excellent article,thanks a lot
Title: Great Job   
Name: Daniel
Date: 2006-07-27 5:25:51 PM
Comment:
Thank you very much. This is just what I needed. Saved me hours of work. Thank you !!!

drazumov@s3ts.com
Title: it is good   
Name: Preeti Singh
Date: 2006-06-27 6:05:23 AM
Comment:
Nice article on this topic and very useful. Thanx!

Preeti
talk_2priti@rediffmail.com
Title: Excelant   
Name: V.Rajamanikandan
Date: 2006-06-20 2:52:37 AM
Comment:
That is nice.......
Title: QUESTION   
Name: VS
Date: 2006-06-03 8:10:11 AM
Comment:
Nice work! By the way how much would this code change if we set EnableViewState="False"? Any ideas?

Thank you.
Title: Mr   
Name: James K
Date: 2006-05-23 12:16:31 PM
Comment:
Nice job
Title: TOO GOOD!   
Name: Neo
Date: 2006-05-21 9:34:58 PM
Comment:
Hey,

Amamzing piece of code,,

Keep it up.

Ta!
Title: web developer   
Name: lakshitha
Date: 2006-03-31 6:21:58 AM
Comment:
Dear Souri

Thanks for your favorable reopened for my e-mail. Your code work properly without error so I want to change code format C# to vb.
I convert it now run now every thing is ok thanks lot of you

Thanks
take care
Lakshitha
lakshithap@dsisamson.com
Title: Date Sorting for different format   
Name: Mohith
Date: 2005-10-26 9:37:17 AM
Comment:
What if the Date displayed is in following format in the grid : Sep 21, 2005 (mon/dd/yyyy) which is 107 date format code in TSQL.
Title: Well done   
Name: Salam Y. ELIAS
Date: 2005-10-14 8:45:21 AM
Comment:
Hi Souri,
Lovely and usefull article, I was justy looking to something like this, it did the job as requested.
Mayebe it would be very interesting to make something general whihi can be plugged to any DG
I have a question about the Numer one "1", you display besides the header when it is clicked. Why do you display this number?

It is always beneficial to the community to have such articles
Title: GREATE   
Name: Jayraj
Date: 2005-08-17 9:24:21 AM
Comment:
Hi,
Thanks for you help. Code developed by you is very useful. It helps me a lot so thank you once again
Title: how do this in vc6 or vc7   
Name: goli_programmer
Date: 2005-08-14 7:14:39 AM
Comment:
hi,
I programming in vc7, and I use MSDATGRD.OCX ( ditributed with visual stodio 6 ), can I add an image to it header?
if non, is there other control that can I use insted of MSDATGRD.OCX and do this?

thanks
Title: Good,   
Name: yuvageetha
Date: 2005-08-01 4:52:55 AM
Comment:
good, it would have been better if u had provided some simple method to do it...
Title: Very Good   
Name: lokesh
Date: 2005-07-28 4:02:58 AM
Comment:
Hi Challa,

This is Good.Can I expect somemore to newusers.
Title: Very good   
Name: Joseph
Date: 2005-06-28 2:08:54 AM
Comment:
A useful help
Title: Ok . Ok   
Name: Ali
Date: 2005-06-10 5:50:53 PM
Comment:
Very Gooooooooooooooooood !?
Title: Limited but interesting   
Name: Arun
Date: 2005-06-10 10:11:35 AM
Comment:
You may want to rethink your abstract since this is far from a "compreensive solution" (which just sounds cool).
But it is a nice start anyway. Thanks.
Title: Very Good   
Name: Mr Sachin Pisal
Date: 2005-06-10 6:11:32 AM
Comment:
G8 Work
Really nice one..and very helpful
Title: Can't wait to apply it to some my applications   
Name: Geoff T
Date: 2005-06-10 3:15:41 AM
Comment:
Thanks for the most generous sharing.
I hope one day I can repay this sort of thing.
Title: Well done   
Name: Ferrol
Date: 2005-06-10 2:43:09 AM
Comment:
Hi Souri,

Nice article on this topic and very useful. Thanx!
Title: Excelant   
Name: Harshad
Date: 2005-06-09 9:47:38 PM
Comment:
It's a very very good article.
Title: very good   
Name: ali
Date: 2005-06-09 5:10:54 PM
Comment:
nice, useful piece of code
Title: ok it is very good   
Name: Lang
Date: 2005-05-31 2:20:38 AM
Comment:
ok code good thank you posted for everybody
Title: Fentastic   
Name: Girish
Date: 2005-05-23 4:55:17 AM
Comment:
Hi Souri, Very Good article, and it has solved my requirement to maximum level. keep it up and share such things to the devlopers comunity.

Regards,
Girish
Title: Reply   
Name: rakesh
Date: 2005-05-09 1:20:04 AM
Comment:
too good
Title: Great article!   
Name: Hui
Date: 2005-05-05 12:05:57 AM
Comment:
Hi Souri,

Great article, and thanks for sharing this!
It has helped me to meet client requirements and amazed a few of my work colleges!

Thanks again!
Title: Excelant   
Name: Kaushal G. Visani
Date: 2005-05-03 4:26:43 AM
Comment:
That is nice,
thanks for yr that kind help
it is very useful me.
i also inspire to send my open source to u
if i create anything new i send it to u

Email : kaushal.mca@gmail.com

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-29 12:41:37 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search