Sorting Generic Collections----转

Sample image

Introduction

By default the List<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 simple User 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.

Collapse
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:

Collapse
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:

Collapse
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();
}
posted @ 2007-08-12 22:48  KidYang  阅读(365)  评论(2编辑  收藏  举报