Makkesk8
Makkesk8

Reputation: 152

C# order listview by column?

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

Answers (8)

Sergey Berezovskiy
Sergey Berezovskiy

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

JSJ
JSJ

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

sihirbazzz
sihirbazzz

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

JD Roberson
JD Roberson

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

shanky
shanky

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

Romil Kumar Jain
Romil Kumar Jain

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

Massimiliano Peluso
Massimiliano Peluso

Reputation: 26737

yourDt.DefaultView.Sort = "Points";
DataView dv = yourDt.DefaultView;

Upvotes: 0

Rahul
Rahul

Reputation: 77936

Do it like

datatableinstance.DefaultView.Sort = "Points ASC"; 

Upvotes: 0

Related Questions