Monday, August 16, 2010

How to enable a List to allow sorting on its class attributes

In my earlier post here, I had tried to convert a List to a DataView, in order to display a tabular result format in an asp:ListView control.

Once I got to display the table, I needed to sort the display based on CustomerID field of the Class “Customer”.

Thanks to Anand Malli, for having a great post on the Code Project for describing it beautifully and in a very simple, extensible manner.

Here is what I landed up doing:

Step #1: Inherited my class from IComparable

public class Customer : IComparable<Customer>
Step #2: Implement the IComparable member
public int CompareTo(Customer other)
{
throw new NotImplementedException();
}
Step #3: Add the Comparison member to the class
public static Comparison<Customer> CustomerIDComparison = delegate(Customer p1, Customer p2)
{
return p1.CustomerID.CompareTo(p2.CustomerID);
};
Step #4: Finally, getting the sort to work before setting the DataSource of the ListView.
lstCustomer.Sort(Customer.CustomerIDComparison);
And that’s it. A big thanks to Anand for sharing this information.
Technorati Tags: ,,,

Convert a List to a DataTable or a DataView

Let’s say we have a class Customer, defined as:

public class Customer
{
public string Name { get; set; }
public string Address { get; set; }
public string ContactNumber { get; set; }
public int CustomerId { get; set; }
public string Email { get; set; }
public string CustomerType { get; set; }
}
Now, let us try to instantiate an object type <List> from this class.
List<Customer> lstCustomer = new List<Customer>();

And let us fill this with some data, I add just 2:
lstCustomer.Add(new Customer { Name="myName1",Address="1234 Spring Pike", ContactNumber="123-456-7899", CustomerId=1002, Email=”abcd@cc.com”, CustomerType="New" });
lstCustomer.Add(new Customer { Name="myName2",Address="1234 Spring Pike", ContactNumber="123-456-7899", CustomerId=1002, Email=”abcd@cc.com”, CustomerType="New" });

Now the actual action, let’s convert this List “lstCustomer” to a DataTable……

//#region Convert the List to a DataTable.

List<Customer> items = lstCustomer;
var tb = new DataTable(typeof(Customer).Name);
PropertyInfo[] props = typeof(Customer).GetProperties(BindingFlags.Public BindingFlags.Instance);
foreach (PropertyInfo prop in props)
{
Type t;
if (prop.PropertyType != null && (!prop.PropertyType.IsValueType (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))))
{
if (!prop.PropertyType.IsValueType)
{
t = prop.PropertyType;
}
else
{
t = Nullable.GetUnderlyingType(prop.PropertyType);
}
}
else
{
t = prop.PropertyType;
}
tb.Columns.Add(prop.Name, t);
}

foreach (Customer item in items)
{
var values = new object[props.Length];
for (int i = 0; i < props.Length; i++)
{
values[i] = props[i].GetValue(item, null);
}
tb.Rows.Add(values);
}

//#endregion
And finally, convert the Datatable to a Dataview
//#region Convert the datatable to dataview.

DataTable dt = tb;
DataView dv = new DataView(dt);

//#endregion
You may very well extract the conversion of a List to a DataTable into a separate method and pass the List “lstCustomer” to that method. I’ll leave the exercise for the rest who are interested to do so. Also, this is not a tested code, so please, no warranties… use it at your own responsibilities and make changes as you wish.
Technorati Tags: ,,,