LIDOR SYSTEMS

Advanced User Interface Controls and Components

Create custom sort operation in ListView .NET control

January 12, 2010

The IntegralUI ListView control supports predefined sorting based on some predefined types. This is determined by ComparerObjectType property which can have one of these values: Double, Integer and String. Although, most of sorting would satisfy comparing basic values, in some cases a sort operation using custom values is needed. In order to do that, we need to create a class that implements the IComparer interface and set the ListItemSorter property to an object of that class.

Download Sample - Custom Sort Operation in ListView .NET

In the following example we will show how to create a class used for sorting DateTime values. At first initialize the ListView with some data:

private void btnInit_Click(object sender, EventArgs e)

{

int j = 0;

 

// Add two columns

LidorSystems.IntegralUI.Lists.ListViewColumn column = null;

for (j = 1; j <= 2; j++)

{

column = new LidorSystems.IntegralUI.Lists.ListViewColumn();

column.HeaderText = String.Format("Header {0}", j.ToString());

column.FooterText = String.Format("Footer {0}", j.ToString());

column.Width = 100;

 

this.listView1.Columns.Add(column);

}

 

// Create a list of items each containg two subitems

LidorSystems.IntegralUI.Lists.ListViewItem item = null;

LidorSystems.IntegralUI.Lists.ListViewSubItem subItem = null;

 

// A variable used to create random dates

DateTime sampleDate = new DateTime(2009, 1, 1);

Random gen = new Random((int)DateTime.Now.Ticks);

 

for (int i = 1; i <= 50; i++)

{

item = new LidorSystems.IntegralUI.Lists.ListViewItem();

 

for (j = 0; j < this.listView1.Columns.Count; j++)

{

subItem = new LidorSystems.IntegralUI.Lists.ListViewSubItem();

 

// Add DateTime only to the second column

if (j == 1)

{

sampleDate = sampleDate.AddDays(gen.Next(27));

subItem.Text = sampleDate.ToString("dd MMM yyyy");

subItem.SortTag = sampleDate;

}

else

subItem.Text = String.Format("Item {0}{1}", i.ToString(), j.ToString());

 

item.SubItems.Add(subItem);

}

 

this.listView1.Items.Add(item);

}

}

One way to trigger sort operation is by handling the ColumnClick event and change the current sort order:

private void listView1_ColumnClick(object sender, LidorSystems.IntegralUI.ObjectClickEventArgs e)

{

if (e.Object is LidorSystems.IntegralUI.Lists.ListViewColumn)

{

LidorSystems.IntegralUI.Lists.ListViewColumn column = (LidorSystems.IntegralUI.Lists.ListViewColumn)e.Object;

 

// Start the Sort operation only when second column is clicked

if (column.Index == 1)

{

switch (this.listView1.Sorting)

{

case SortOrder.Ascending:

this.listView1.Sorting = SortOrder.Descending;

break;

case SortOrder.Descending:

this.listView1.Sorting = SortOrder.Ascending;

break;

default:

this.listView1.Sorting = SortOrder.Descending;

break;

}

 

// Apply the custom sort operation

this.listView1.ListItemSorter = new DateTimeComparer(this.listView1.Sorting, column.Index);

}

}

}

A class which will compare DateTime values is presented in the code below.

public class DateTimeComparer : System.Collections.IComparer

{

private System.Windows.Forms.SortOrder sortType = System.Windows.Forms.SortOrder.Ascending;

private int col = -1;

 

public DateTimeComparer()

{

}

 

public DateTimeComparer(System.Windows.Forms.SortOrder order, int colIndex)

{

sortType = order;

col = colIndex;

}

 

public int Compare(object x, object y)

{

// Switch the objects if the sort order is Descending

if (sortType == System.Windows.Forms.SortOrder.Descending)

{

object temp = x;

x = y;

y = temp;

}

 

object firstDate = null;

object secondDate = null;

 

if (col >= 0)

{

if (col < (x as LidorSystems.IntegralUI.Lists.ListViewItem).SubItems.Count)

firstDate = (x as LidorSystems.IntegralUI.Lists.ListViewItem).SubItems[col].SortTag;

if (col < (y as LidorSystems.IntegralUI.Lists.ListViewItem).SubItems.Count)

secondDate = (y as LidorSystems.IntegralUI.Lists.ListViewItem).SubItems[col].SortTag;

}

 

// Check objects are not empty

if (firstDate != null && secondDate != null)

{

// Compare object values only if they contain DateTime value

if (firstDate.GetType() == typeof(DateTime) && secondDate.GetType() == typeof(DateTime))

return DateTime.Compare((DateTime)firstDate, (DateTime)secondDate);

}

 

return 0;

}

}

A sample project in C# and VB showing how to create custom sort operation in ListView is available for download from here: ListView with Custom Sort Operation

Newsletter


Sign-up to our newsletter and you will receive news on upcoming events, latest articles, samples and special offers.
Name: Email: *
*By checking this box, I agree to receive a newsletter from Lidor Systems in accordance with the Privacy Policy. I understand that I can unsubscribe from these communications at any time by clicking on the unsubscribe link in all emails.