Windows Develop Bookmark and Share   
 index > Windows Forms Data Controls and Databinding > Sorting items in listview in C#
 

Sorting items in listview in C#


private int sortColumn = -1;

private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
// Determine whether the column is the same as the last column clicked.
if (e.Column != sortColumn)
{
// Set the sort column to the new column.
sortColumn = e.Column;
// Set the sort order to ascending by default.
listView1.Sorting = SortOrder.Ascending;
}
else
{
// Determine what the last sort order was and change it.
if (listView1.Sorting == SortOrder.Ascending)
listView1.Sorting = SortOrder.Descending;
else
listView1.Sorting = SortOrder.Ascending;
}

// Call the sort method to manually sort.
listView1.Sort();
// Set the ListViewItemSorter property to a new ListViewItemComparer
// object.
this.listView1.ListViewItemSorter = new ListViewItemComparer(e.Column,listView1.Sorting);
}
}

class ListViewItemComparer : IComparer
{
private int col;
private SortOrder order;
public ListViewItemComparer()
{
col = 0;
order = SortOrder.Ascending;
}
public ListViewItemComparer(int column, SortOrder order)
{
col = column;
this.order = order;
}
public int Compare(object x, object y)
{
int returnVal= -1;
returnVal = String.Compare(((ListViewItem)x).SubItems[col].Text,
((ListViewItem)y).SubItems[col].Text);

if (order == SortOrder.Descending)
// Invert the value returned by String.Compare.
returnVal = 1;
return returnVal;
}
}
chaitu2  Saturday, December 08, 2007 12:04 AM
I added a regular expression to the Compare procedure to see if the strings are numbers. If they are I compare them manually other wise I use a string.compare

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ListViewSortCS
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private int sortColumn = -1;

private void Form1_Load(object sender, EventArgs e)
{
listView1.View = View.Details;
listView1.Columns.Add("String", 100);
listView1.Columns.Add("Number", 100);

for (int x = 0; x < 21; x++)
{
ListViewItem li = new ListViewItem("Item " + x.ToString());
li.SubItems.Add(x.ToString());
listView1.Items.Add(li);
}
}

private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
// Determine whether the column is the same as the last column clicked.
if (e.Column != sortColumn)
{
// Set the sort column to the new column.
sortColumn = e.Column;
// Set the sort order to ascending by default.
listView1.Sorting = SortOrder.Ascending;
}
else
{
// Determine what the last sort order was and change it.
if (listView1.Sorting == SortOrder.Ascending)
listView1.Sorting = SortOrder.Descending;
else
listView1.Sorting = SortOrder.Ascending;
}

// Call the sort method to manually sort.
listView1.Sort();
// Set the ListViewItemSorter property to a new ListViewItemComparer
// object.
this.listView1.ListViewItemSorter = new ListViewItemComparer(e.Column, listView1.Sorting);
}
}

class ListViewItemComparer : System.Collections.IComparer
{
private int col;
private SortOrder order;
public ListViewItemComparer()
{
col = 0;
order = SortOrder.Ascending;
}
public ListViewItemComparer(int column, SortOrder order)
{
col = column;
this.order = order;
}
public int Compare(object x, object y)
{
string s1 = ((ListViewItem)x).SubItems[col].Text;
string s2 = ((ListViewItem)y).SubItems[col].Text;
int returnVal = 0;
System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(@"^\d+$");
if (!r.IsMatch(s1) && !r.IsMatch(s2))
{
returnVal = String.Compare(s1 , s2);
}
else
{
int x1 = int.Parse( s1);
int x2 = int.Parse(s2);
if(x1 == x2)
{
returnVal = 0;
}
else if(x1> x2)
{
returnVal=1;
}
else
{
returnVal=-1;
}
}
// Determine whether the sort order is descending.
if (order == SortOrder.Descending)
// Invert the value returned by String.Compare.
returnVal = returnVal * -1;
return returnVal;
}
}
}

Ken Tucker  Saturday, December 08, 2007 5:49 PM
If the radio button is checked call the listview's ColumnClick event passing in the column you want sorted

private void rbNumber_CheckedChanged(object sender, EventArgs e)
{
if (rbNumber.Checked)
{
listView1_ColumnClick(listView1, new ColumnClickEventArgs(1));
}
}

private void rbString_CheckedChanged(object sender, EventArgs e)
{
if (rbString.Checked)
{
listView1_ColumnClick(listView1, new ColumnClickEventArgs(0));
}
}
Ken Tucker  Sunday, December 09, 2007 5:41 PM
I added a regular expression to the Compare procedure to see if the strings are numbers. If they are I compare them manually other wise I use a string.compare

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ListViewSortCS
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private int sortColumn = -1;

private void Form1_Load(object sender, EventArgs e)
{
listView1.View = View.Details;
listView1.Columns.Add("String", 100);
listView1.Columns.Add("Number", 100);

for (int x = 0; x < 21; x++)
{
ListViewItem li = new ListViewItem("Item " + x.ToString());
li.SubItems.Add(x.ToString());
listView1.Items.Add(li);
}
}

private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
// Determine whether the column is the same as the last column clicked.
if (e.Column != sortColumn)
{
// Set the sort column to the new column.
sortColumn = e.Column;
// Set the sort order to ascending by default.
listView1.Sorting = SortOrder.Ascending;
}
else
{
// Determine what the last sort order was and change it.
if (listView1.Sorting == SortOrder.Ascending)
listView1.Sorting = SortOrder.Descending;
else
listView1.Sorting = SortOrder.Ascending;
}

// Call the sort method to manually sort.
listView1.Sort();
// Set the ListViewItemSorter property to a new ListViewItemComparer
// object.
this.listView1.ListViewItemSorter = new ListViewItemComparer(e.Column, listView1.Sorting);
}
}

class ListViewItemComparer : System.Collections.IComparer
{
private int col;
private SortOrder order;
public ListViewItemComparer()
{
col = 0;
order = SortOrder.Ascending;
}
public ListViewItemComparer(int column, SortOrder order)
{
col = column;
this.order = order;
}
public int Compare(object x, object y)
{
string s1 = ((ListViewItem)x).SubItems[col].Text;
string s2 = ((ListViewItem)y).SubItems[col].Text;
int returnVal = 0;
System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(@"^\d+$");
if (!r.IsMatch(s1) && !r.IsMatch(s2))
{
returnVal = String.Compare(s1 , s2);
}
else
{
int x1 = int.Parse( s1);
int x2 = int.Parse(s2);
if(x1 == x2)
{
returnVal = 0;
}
else if(x1> x2)
{
returnVal=1;
}
else
{
returnVal=-1;
}
}
// Determine whether the sort order is descending.
if (order == SortOrder.Descending)
// Invert the value returned by String.Compare.
returnVal = returnVal * -1;
return returnVal;
}
}
}

Ken Tucker  Saturday, December 08, 2007 5:49 PM
excellent thank you very much its working is it possible to call the this column click event in the following event

private void radioButton1_CheckedChanged(object sender, EventArgs e)
{


}
chaitu2  Saturday, December 08, 2007 8:08 PM
If the radio button is checked call the listview's ColumnClick event passing in the column you want sorted

private void rbNumber_CheckedChanged(object sender, EventArgs e)
{
if (rbNumber.Checked)
{
listView1_ColumnClick(listView1, new ColumnClickEventArgs(1));
}
}

private void rbString_CheckedChanged(object sender, EventArgs e)
{
if (rbString.Checked)
{
listView1_ColumnClick(listView1, new ColumnClickEventArgs(0));
}
}
Ken Tucker  Sunday, December 09, 2007 5:41 PM
thank you very much
chaitu2  Sunday, December 09, 2007 11:31 PM
Hi Ken,

I went step-by-step with sorting listView, but in my code is doing nothing... I dont know if I miss sth.. my code contains other algorithms, but it shouldnt affect... Sad
It writes no error, just it is not working and have no idea where can be a mistake Sad

Thanks a lot...
tweeta  Tuesday, April 29, 2008 5:41 PM
It is ok, I just find a mistake Smile but anyway thanks for this forum Smile
tweeta  Tuesday, April 29, 2008 5:57 PM

You can use google to search for other answers

Custom Search

More Threads

• unable to pre-select a value in my combobox column
• validating different text fields
• Best method for binding textboxes to function results from SQL-DB
• Click Click Click and the DataGridViewComboBoxColumn just won't drop down
• Bindable Attribute problem
• Resource Files and Databinding
• Need Help: Image In A Datagrid Column (code partially from here)?
• Data Binding, Data Modules and designer support
• cancel a RowLeave
• Precision data