Sorting Generic Collections----转
Introduction
By default theList<T>
class supports the following sort methods Sort(Icomparer<T>)
and Sort(Comparison<T>)
. This does not help us to sort our collections by datatype of the property. This artical help us to fill the above gap. A User Class
Let us have a simpleUser
class that exposes Id, UserName, JoinDate, UserType and Active Status properties. Let us take the simple List<T>
Collection class to hold the list of User
objects. The SortableList<T>
inherits the List<T>
generic class. The Sort
method takes to arguments. Let us say propertyName and ascending. ![](http://www.codeproject.com/images/minus.gif)
public enum UserTypeEnum
{
Manager,
ProjectLead,
TeamLead,
SeniorSoftwareEngineer,
SoftwareEngineer
}
/// <summary />
/// Summary description for User
/// </summary />
public class User
{
public User(int id, string userName,DateTime joinDate,
UserTypeEnum userType, bool isActive)
{
this.id = id;
this.userName = userName;
this.joinDate = joinDate;
this.userType = userType;
this.isActive = isActive;
}
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
private string userName = string.Empty ;
public string UserName
{
get { return userName; }
set { userName = value; }
}
private DateTime joinDate = DateTime.MinValue;
public DateTime JoinDate
{
get { return joinDate; }
set { joinDate = value; }
}
private UserTypeEnum userType = UserTypeEnum.SoftwareEngineer;
public UserTypeEnum UserType
{
get { return userType; }
set { userType = value; }
}
private bool isActive = false;
public bool IsActive
{
get { return isActive; }
set { isActive = value; }
}
}
Sortable List:
![](http://www.codeproject.com/images/minus.gif)
public class SortableList<T>: List<T>
{
private string _propertyName;
private bool _ascending;
public void Sort(string propertyName, bool ascending)
{
//Flip the properties if the parameters are the same
if (_propertyName == propertyName && _ascending == ascending)
_ascending = !ascending;
//Else, new properties are set with the new values
else
{
_propertyName = propertyName;
_ascending = ascending;
}
PropertyDescriptorCollection properties
= TypeDescriptor.GetProperties(typeof(T));
PropertyDescriptor propertyDesc = properties.Find(propertyName, true);
// Apply and set the sort, if items to sort
PropertyComparer<T> pc = new PropertyComparer<T>(propertyDesc,
(_ascending) ? ListSortDirection.Ascending :
ListSortDirection.Descending);
this.Sort(pc);
}
The GetProperties
of TypeDescriptor
class returns the collection of properties on a component or type and Find
method of PropertyDescriptorCollection
returns the PropertyDescriptor with the specified name, using a Boolean to indicate whether to ignore case. A PropertyDescriptor
with the specified name, or a null reference if the property does not exist.Now, we can use any property comparer class to compare the values of the property. Here I use
PropertyComaparer<T>
class that wrote by Rockford Lhotka in MSDN.PropertyComparer
builds on a comparison algorithm based built by Rockford Lhotka and turns it into a generic property comparer for any type. (Note: While a detailed analysis of the comparer is beyond the scope of this article, a brief discussion will suffice, although I urge you to read Rocky's great article and inspect the code sample).That's it! We are ready to implement this sortable list into our ASP.NET pages.
Code Behind File:
![](http://www.codeproject.com/images/minus.gif)
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SortableList<user> list = BuildList();
Cache.Insert("Users", list, null,
System.Web.Caching.Cache.NoAbsoluteExpiration,
System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.High,
null);
UsersGridView.DataSource = list;
UsersGridView.DataBind();
}
}
protected void UsersGridView_PageIndexChanging(object sender,
GridViewPageEventArgs e)
{
SortableList<user> list = Cache["Users"] as SortableList<user>;
UsersGridView.PageIndex = e.NewPageIndex;
UsersGridView.DataSource = list;
UsersGridView.DataBind();
}
protected void UsersGridView_Sorting(object sender,
GridViewSortEventArgs e)
{
SortableList<user> list = Cache["Users"] as SortableList<user>;
list.Sort(e.SortExpression,
(e.SortDirection == SortDirection.Ascending));
//Add the sorted collection back to the cache
Cache.Insert("Users", list, null,
System.Web.Caching.Cache.NoAbsoluteExpiration,
System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.High,
null);
UsersGridView.DataSource = list;
UsersGridView.DataBind();
}
KidYang