Introduction:
Sorting in a GridView is a common scenario
required by most of the web applications. In my previous articles I discussed
GridView Sorting Using Bound Columns and Sorting GridView with Autogenerated
Columns. In both of my previous articles I used the help of DataView object to
sort the container. Most of the enterprise applications take advantage of the
entity classes which allow the basis for object oriented programming. In this
article I will explain how you can sort the GridView control which uses a
generic list as its data source.
Creating a
GridView Control:
Let's first create a GridView control. The GridView will contain two
bound columns and two template columns. Take a look at the code below:
<asp:GridView EnableSortingAndPagingCallbacks="false" AllowSorting="true" ID="gvUsers" runat="server" AutoGenerateColumns="false" OnSorting="gvUsers_Sorting" > <Columns> <asp:BoundField DataField="FirstName" HeaderText="First Name" SortExpression="FirstName" /> <asp:BoundField DataField = "LastName" HeaderText= "Last Name" SortExpression="LastName" /> <asp:TemplateField HeaderText="Class Code" SortExpression="ClassCode"> <ItemTemplate> <asp:Label ID="lblClassCode" runat="server" Text='<%# Eval("ClassCode") %>' /> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> |
Notice that I have also included the SortExpression for
all the columns of the GridView control. The SortExpression denotes the field
which is used for sorting the GridView.
Creating an
Entity Class
I will create a very simple User entity
class. Once, the class is created I will fill the generic List with
the objects and send it back to the client where they are displayed in the
GridView.
Take a look at the code below which creates a very simple
entity class User.cs: public class User { private string firstName; private string lastName; private string classCode;
public string FirstName { get { return this.firstName; } set { this.firstName = value; } }
public string LastName { get { return this.lastName; } set { this.lastName = value; } }
public string ClassCode { get { return this.classCode; } set { this.classCode = value; } }
public User() {
} }
|
Implementing GetAllUsers Method
The GetAllUsers
method is responsible for fetching the list of users and sending the list
back to the client. In the code below I am using a generic list which can
contain objects of type User.
public List GetAllUsers() { List users = new List();
string connectionString = @"Server=localhost;Database=School;Trusted_Connection=true"; SqlConnection myConnection = new SqlConnection(connectionString);
SqlCommand myCommand = new SqlCommand("SELECT * FROM Users", myConnection);
myConnection.Open(); SqlDataReader reader = myCommand.ExecuteReader(); while (reader.Read()) { User user = new User(); user.FirstName = reader["FirstName"] as String; user.LastName = reader["LastName"] as String; user.ClassCode = reader["ClassCode"] as String;
users.Add(user); }
myConnection.Close(); myCommand.Dispose();
return users;
}
|
Binding Data Source to GridView Control
Now, that
we have filled the list with User objects we can bind the list to the GridView.
Take a look at the code below which binds the list of users to the GridView
control.
private void BindData() { User user = new User(); gvUsers.DataSource = user.GetAllUsers(); gvUsers.DataBind();
}
|
Although
you have bind the list to the GridView, the sorting mechanism is not yet
enabled. In order to deal with sorting which is dependent on the list of objects
you will need to create a Comparer which implements the IComparer
interface. The IComparer interface contains a method name CompareTo, which
you can implement to compare the objects.
Implementing the IComparer Interface
We will
create a class called GenericComparer which will implement the IComparer
interface. The GenericComparer class contains bunch of stuff so let's check it
out in detail.
SortDirection : The sort direction indicates
the direction of the sort. This can be ascending or descending.
public SortDirection SortDirection { get { return this.sortDirection; } set { this.sortDirection = value; } } |
GenericComparer
Constructor : The contructor takes two arguments namely, sortExpression and
sortDirection. The sortExpression is the name of the GridView column to sort and
sortDirection denotes the direction in which the column has to be sorted. The
sortDirection can be ascending or descending.
public GenericComparer(string sortExpression, SortDirection sortDirection) { this.sortExpression = sortExpression; this.sortDirection = sortDirection; }
|
CompareTo Method: The CompareTo method is the place where all the
fun happens. The CompareTo method takes a generic T as an argument which means
it can accept any type of object. Then it uses the sortExpression to extract the
property out of the type and finally it performs the comparison on the
properties.
public int Compare(T x, T y) { PropertyInfo propertyInfo = typeof(T).GetProperty(sortExpression); IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null); IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null);
if (SortDirection == SortDirection.Ascending) { return obj1.CompareTo(obj2); } else return obj2.CompareTo(obj1);
}
|
Using the Code
An ideal place to call the sorting
method is inside the GridView_Sorting event which is fired when you clicked the
column header of the GridView control. Take a look at the code below:
protected void gvUsers_Sorting(object sender, GridViewSortEventArgs e) { User user = new User(); List users = user.GetAllUsers();
users.Sort(new GenericComparer(e.SortExpression, GridViewSortDirection));
gvUsers.DataSource = users; gvUsers.DataBind(); }
|
Now,
if you click on the GridView header it will be sorted based on what column you
clicked on.
I hope you liked the article, happy coding!