
ASP.NET GridView: Multiple Column Sort
The native
ASP.NET GridView allows for the sorting of data by setting the Grid's
AllowSorting property to True. With AllowSorting enabled, header row cells contain hyperlinks, which when clicked, sort the
GridView. There are several
GridView properties and events available which can be used for the customization of the
GridView's sort.
- The Sort method, defined as Sort ( string sortExpression, SortDirection sortDirection ), sorts the GridView based upon the specified sort expression and direction.
- The Sorting event occurs when the hyperlink column heading is clicked, but before the GridView has handled the sorting of the data.
- The Sorted event occurs when the hyperlink column heading is clicked, but after the GridView has sorted the datasource.
- The RowCreated event occurs when a row is created in the GridView.
- The SortDirection property gets the sort direction of the column being sorted.
- The SortExpression property gets the sort expression associated with the column being sorted.
The default sort action of the
GridView sorts only by a single column. Using the available sort related events and properties it is rather easy to create a
GridView that can be sorted by multiple columns. The following example is for a
GridView than can be sorted by multiple columns. In this example the columns are sorted in the order they are clicked by a tri-state function. Clicking on a column heading will set a columns sort state to be
Ascending, Descending or
Off. The columns in the
GridView are sorted based upon in which they are click or turned on. When the sort state of a column is
Off it is removed from the sort.
1
using System;
2
using System.Collections.Generic;
3
using System.Web.UI;
4
using System.Web.UI.WebControls;
5
using System.Data;
6
7
/**//// <summary>
8
/// MySortItem is a class that is used to in a List<T> to store the sort columns and thier order
9
/// </summary>
10
public class MySortItem
11
...{
12
private string columnname;
13
public string ColumnName
14
...{
15
get
16
...{
17
return columnname;
18
}
19
set
20
...{
21
columnname = value;
22
}
23
}
24
private SortDirection columnsort;
25
public SortDirection ColumnSort
26
...{
27
get
28
...{
29
return columnsort;
30
}
31
set
32
...{
33
columnsort = value;
34
}
35
}
36
public string SortToString( SortDirection cs )
37
...{
38
string s = ( cs == SortDirection.Ascending ) ? "asc" : "desc";
39
return s;
40
}
41
42
}
43
44
public partial class _Default : System.Web.UI.Page
45
...{
46
DataSet ds = new DataSet ();
47
// List for holding sorted columns, their order and their direction
48
List<MySortItem> sl;
49
50
51
protected void Page_Load( object sender, EventArgs e )
52
...{
53
// If the Column Sort List does not exist, create it. the list is stored in a session variable
54
if ( Session["sortitems"] == null )
55
...{
56
Session["sortitems"] = new List<MySortItem> ();
57
}
58
sl = (List<MySortItem>) Session["sortitems"];
59
60
if ( !Page.IsPostBack )
61
...{
62
// Procedure for binding the datasource with the DataGrid
63
BindDataGrid (GridView1);
64
}
65
}
66
67
/**//// <summary>
68
/// Called from within the application to Bind the DataGrid to a datasource. in this cases it is the default view of a table.
69
/// </summary>
70
protected void BindDataGrid(GridView gv)
71
...{
72
// Read data from an XML file
73
ds.ReadXml ( Server.MapPath ( "~/App_Data/Data.xml" ) );
74
75
// build the sort expression
76
string sortexp = "";
77
for ( int i = 0; i < sl.Count; i++ )
78
...{
79
sortexp = ( i == 0 ) ? sl[i].ColumnName + " " + sl[i].SortToString ( sl[i].ColumnSort ) : sortexp + "," + sl[i].ColumnName + " " + sl[i].SortToString ( sl[i].ColumnSort );
80
}
81
82
//Set label text to display the sort expression on the page for the user
83
Label3.Text = sortexp;
84
// set the datasource's table default view to indicate sorting; a datatable could also be used directly. In this example a datasource
85
// was used due to dynmaic XML data loading
86
ds.Tables[0].DefaultView.Sort = sortexp;
87
// set the datagrid's datasource
88
gv.DataSource = ds.Tables[0].DefaultView;
89
gv.DataBind ();
90
}
91
92
/**//// <summary>
93
/// Assigned to the GridView's PagIndexChanging event. This is used if the GridView allows for paging.
94
/// </summary>
95
/// <param name="sender"></param>
96
/// <param name="e"></param>
97
protected void GridView1_PageIndexChanging( object sender, GridViewPageEventArgs e )
98
...{
99
try
100
...{
101
if ( sender is GridView )
102
...{
103
( (GridView) sender ).PageIndex = e.NewPageIndex;
104
BindDataGrid (GridView1);
105
e.Cancel = false;
106
}
107
}
108
catch
109
...{
110
111
e.Cancel = true;
112
}
113
}
114
115
/**//// <summary>
116
/// Assigned to the GridView's Sorting event.
117
/// </summary>
118
/// <param name="sender"></param>
119
/// <param name="e"></param>
120
protected void GridView1_Sorting( object sender, GridViewSortEventArgs e )
121
...{
122
try
123
...{
124
// Scroll through the list and see if the clicked GridView column exists in the sort list.
125
// If there is an entry for the column then change the order or remove the column from the list (tri-state)
126
bool found = false;
127
for ( int i = 0; i < sl.Count; i++ )
128
...{
129
if ( sl[i].ColumnName == e.SortExpression.ToString () )
130
...{
131
found = true;
132
switch ( sl[i].ColumnSort )
133
...{
134
case SortDirection.Descending:
135
sl[i].ColumnSort = SortDirection.Ascending;
136
break;
137
case SortDirection.Ascending:
138
sl.RemoveAt ( i );
139
break;
140
}
141
}
142
}
143
if ( !found )
144
...{
145
MySortItem si = new MySortItem ();
146
si.ColumnName = e.SortExpression.ToString ();
147
si.ColumnSort = SortDirection.Descending;
148
sl.Add ( si );
149
}
150
151
BindDataGrid (GridView1);
152
//accept column sort
153
e.Cancel = false;
154
}
155
catch ( Exception )
156
...{
157
//error so cancel
158
e.Cancel = true;
159
}
160
}
161
162
/**//// <summary>
163
/// Assigned to the GridView's RowCreated event.
164
/// </summary>
165
/// <param name="sender"></param>
166
/// <param name="e"></param>
167
protected void GridView1_RowCreated( object sender, GridViewRowEventArgs e )
168
...{
169
// add images to the column header to indicate sort of each column
170
if ( e.Row.RowType == DataControlRowType.Header )
171
...{
172
foreach ( TableCell tc in e.Row.Cells )
173
...{
174
if ( tc.HasControls () )
175
...{
176
// search for the header link
177
LinkButton lnk = (LinkButton) tc.Controls[0];
178
if ( ( lnk != null ) & ( sl != null ) )
179
...{
180
// Get the position of the column in the List<t>
181
int i = sl.FindIndex ( delegate ( MySortItem s )
182
...{
183
return s.ColumnName == lnk.CommandArgument;
184
} );
185
// if the column is found in the list
186
if ( i >= 0 )
187
...{
188
System.Web.UI.WebControls.Image img = new System.Web.UI.WebControls.Image ();
189
//set the appropriate image
190
img.ImageUrl = "~/images/" + ( sl[i].ColumnSort == SortDirection.Ascending ? "asc" : "desc" ) + ".gif";
191
// add space and the sort image to header
192
if ( sl[i].ColumnName == lnk.CommandArgument )
193
...{
194
tc.Controls.Add ( new LiteralControl ( " " ) );
195
tc.Controls.Add ( img );
196
}
197
}
198
}
199
}
200
}
201
}
202
}
203
}
This is all it takes to have an
ASP.NET GridView that can be sorted by multiple columns.
Labels: .NET, C#, Code
posted by Brad Prendergast at 6:19:00 AM
(1 comments)
Links to this post
Permalink