Reputation: 152
Im building a datatable with 2 columns with listview and i need to order the datatable by the second column.
It look something like this:
Name - Points
------------------
John - 10
Peter - 14
Marcus - 9
So how do I order it by points?
SOLVED!!
private class PointsComparer : IComparer
{
private const int pointsColumnIndex = 1;
public int Compare(object x, object y)
{
ListViewItem listX = (ListViewItem)x;
ListViewItem listY = (ListViewItem)y;
// Convert column text to numbers before comparing.
// If the conversion fails, just use the value 0.
decimal listXVal, listYVal;
try
{
listXVal = Decimal.Parse(listX.SubItems[pointsColumnIndex].Text);
}
catch
{
listXVal = 0;
}
try
{
listYVal = Decimal.Parse(listY.SubItems[pointsColumnIndex].Text);
}
catch
{
listYVal = 0;
}
return (-Decimal.Compare(listXVal, listYVal));
}
}
This worked as a charm for me.
Upvotes: 1
Views: 6012
Reputation: 236308
Use ListViewItemSorter property to set custom IComparer
for your items. Then simply call Sort()
method:
// adding data
listView1.Items.Add(new ListViewItem(new string[] { "John", "10" }));
listView1.Items.Add(new ListViewItem(new string[] { "Peter", "14" }));
listView1.Items.Add(new ListViewItem(new string[] { "Markus", "9" }));
// setting comparer and sorting
listView1.ListViewItemSorter = new PointsComparer();
listView1.Sort();
Here is sample of comparer which you can use to compare points:
private class PointsComparer : IComparer
{
private const int pointsColumnIndex = 1;
public int Compare(object x, object y)
{
int pointsX = Int32.Parse(((ListViewItem)x).SubItems[pointsColumnIndex].Text);
int pointsY = Int32.Parse(((ListViewItem)y).SubItems[pointsColumnIndex].Text);
return pointsX.CompareTo(pointsY);
}
}
Or, as I posted previously, you can use comparer by column text from msdn sample.
UPDATE: You can pass desired sort order to instance of your comparer:
private class PointsComparer : IComparer
{
private const int pointsColumnIndex = 1;
private SortOrder _sortOrder;
public PointsComparer(SortOrder sortOrder)
{
_sortOrder = sortOrder;
}
public int Compare(object x, object y)
{
int pointsX = Int32.Parse(((ListViewItem)x).SubItems[pointsColumnIndex].Text);
int pointsY = Int32.Parse(((ListViewItem)y).SubItems[pointsColumnIndex].Text);
int comparisonResult = pointsX.CompareTo(pointsY);
switch (_sortOrder)
{
case SortOrder.Ascending:
return comparisonResult;
case SortOrder.Descending:
return (-1) * comparisonResult;
default:
return 0;
}
}
}
Then use it like this:
listView1.ListViewItemSorter = new PointsComparer(SortOrder.Descending);
Upvotes: 2
Reputation: 5691
here are some samples
Paste the following code into the ColumnClick event for the ListView control:
private void listView1_OnColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
{
ListViewSorter Sorter = new ListViewSorter();
listView1.ListViewItemSorter = Sorter;
if (!(listView1.ListViewItemSorter is ListViewSorter))
return;
Sorter = (ListViewSorter) listView1.ListViewItemSorter;
if (Sorter.LastSort == e.Column)
{
if (listView1.Sorting == SortOrder.Ascending)
listView1.Sorting = SortOrder.Descending;
else
listView1.Sorting = SortOrder.Ascending;
}
else{
listView1.Sorting = SortOrder.Descending;
}
Sorter.ByColumn = e.Column;
listView1.Sort ();
}
public class ListViewSorter : System.Collections.IComparer
{
public int Compare (object o1, object o2)
{
if (!(o1 is ListViewItem))
return (0);
if (!(o2 is ListViewItem))
return (0);
ListViewItem lvi1 = (ListViewItem) o2;
string str1 = lvi1.SubItems[ByColumn].Text;
ListViewItem lvi2 = (ListViewItem) o1;
string str2 = lvi2.SubItems[ByColumn].Text;
int result;
if (lvi1.ListView.Sorting == SortOrder.Ascending)
result = String.Compare (str1, str2);
else
result = String.Compare (str2, str1);
LastSort = ByColumn;
return (result);
}
public int ByColumn
{
get {return Column;}
set {Column = value;}
}
int Column = 0;
public int LastSort
{
get {return LastColumn;}
set {LastColumn = value;}
}
int LastColumn = 0;
}
sort sample http://support.microsoft.com/kb/319401
multi sort
http://www.c-sharpcorner.com/uploadfile/nipuntomar/sort-a-multicolumn-listview-in-C-Sharp/
Upvotes: 0
Reputation: 718
As Reniuz said, For better performance order it within the SQL query and for Xtra-gain implement it in a dictionary or an arrayList or a Generic List ( List ) and also you can use Datagridview to show on GUI .. SQL Query Syntax :
Select [Column1], [Column2] from [YourTable] order by [ColumnWhichYouWantToOrder1], [ColumnWhichYouWantToOrder2] [ {ASC} or {DESC} ]
Rules for Syntax :
DESC ordering sorts from last no to first or Z to A
ASC ordering sorts from first to last or A to Z
ASC is the default. So if you order by ASC you can use as ..order by [Column] ... no need to write ASC
when you sort with more than 1 column, SQL starts to order from left column to right.
Upvotes: 0
Reputation: 599
This helped me out with the same issue. http://support.microsoft.com/kb/319401
I found that I had to tweak some of the math as when sorting by numbers it sometimes would put 1,10,11,12,2,20,21,etc
Upvotes: 0
Reputation: 396
// Sorting data based on ID
Let's suppose dt is your datatable object to be sorted. You can do as mentioned below:
dt.DefaultView.Sort = "Points ASC";
now dt is your sorted datatable
Upvotes: 0
Reputation: 20775
DataView dv = dt.DefaultView;
//apply the sort on CustomerSurname column
dv.Sort = "CustomerSurname";
//save our newly ordered results back into our datatable
dt = dv.ToTable();
Upvotes: 0
Reputation: 26737
yourDt.DefaultView.Sort = "Points";
DataView dv = yourDt.DefaultView;
Upvotes: 0