Sorting in ListView

6 posts, 1 answers
  1. Robert
    Robert avatar
    10 posts
    Member since:
    Apr 2012

    Posted 15 Jun 2012 Link to this post

    I want to sort my ListView on Clicking a column
    in similarity to what we do with General ListView in .Net

    private void listView1_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
    {
    }
    Imagine the column Header is "Count" and the "Name" is "Column_0" In it's default behavior of the ListView it is sorted with this logic (as strings): 79 < 8 < 89 < 9 , .... The Designer's Code :
    Telerik.WinControls.UI.ListViewDetailColumn listViewDetailColumn2 = new Telerik.WinControls.UI.ListViewDetailColumn("Column 1", "Count");
    Telerik.WinControls.Data.SortDescriptor sortDescriptor1 = new Telerik.WinControls.Data.SortDescriptor();
    I have written a comparer like this for the Default .Net Windows Forms Controls ListView :
    public class CountSort: IComparer
    {
        public int Compare(object x, object y)
        {
            Product w1 = (Product)x;           
     
            Product w2 = (Product)y;
     
            if (w1.Count> w2.Count)
                return 1;
            if (w1.Count< w2.Count)
                return -1;
            else
                return 0;
        }
    }
    But now don't know how to link all the items and figure this out. needed help, thanks
  2. Ivan Todorov
    Admin
    Ivan Todorov avatar
    688 posts

    Posted 20 Jun 2012 Link to this post

    Hi Robert,

    Thank you for contacting us.

    RadListView supports sorting when clicking on column headers out of the box. To enable this functionality, you need to set the following properties:
    this.radListView1.EnableSorting = true;
    this.radListView1.EnableColumnSort = true;

    The default comparer that is used internally in RadListView checks the SortDescriptors collection and sorts the values according to the fields described in that collection. This means that if you add your data as numbers (not as string) they will be sorted numerical order.

    In case you do not want to use the default comparer, you can replace it by setting:
    this.radListView1.ListViewElement.DataView.Comparer = new ListViewCustomComparer(this.radListView1.ListViewElement);

    Note that I pass a reference to my ListViewElement to the comparer so I can check the SortDescriptors collection manually inside the comparer. Below is a sample implementation of a RadListView comparer:
    public class ListViewCustomComparer : IComparer<ListViewDataItem>
    {
        RadListViewElement listViewElement;
     
        public ListViewCustomComparer(RadListViewElement listViewElement)
        {
            this.listViewElement = listViewElement;
        }
     
        public int Compare(ListViewDataItem x, ListViewDataItem y)
        {
            foreach (SortDescriptor descriptor in this.listViewElement.SortDescriptors)
            {
                if (descriptor.PropertyName == "Freight")
                {
                    decimal row1Freight = (decimal)x["Freight"];
                    decimal row2Freight = (decimal)y["Freight"];
     
                    int result = row1Freight.CompareTo(row2Freight);
     
                    if (descriptor.Direction == ListSortDirection.Descending)
                    {
                        result *= -1;
                    }
     
                    return -1;
                }
            }
     
            return 0;
        }
    }

    Note that if you set the EnableColumnSortProperty to true, you do not need to manually add SortDescriptors to RadListView. This is done internally when you click on the column headers.

    I hope you find this information useful. Feel free to ask if you have any additional questions.

    All the best,
    Ivan Todorov
    the Telerik team
    RadControls for WinForms Q2'12 release is now live! Check out what's new or download a free trial >>
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Robert
    Robert avatar
    10 posts
    Member since:
    Apr 2012

    Posted 09 Jul 2012 Link to this post

    Thanks Ivan,
    It should do the job nicely,
    busy on another pieces of the code, will try it soon and comment on this thread if needed.
    --
    Robert
  5. Robert
    Robert avatar
    10 posts
    Member since:
    Apr 2012

    Posted 21 Jul 2012 Link to this post

    Came back to this thread,
    Hi again,

    There are 3 related questions on this :

    First : Don't know why I can't change the column Names in a ListView,
             When inside the Collection Editor I add any Column It's color is gray and doesn't let me to change it's name,
             So all the names are like : Column 0, Column 1, ....

    Second :
                 Still couldn't make the behavior you said work. You mentioned if I add a descriptor it could do the sorting logic of numerical values
                 by default. Although I added a SortDescriptor for the "Count Column" I mentioned earlier It didn't react on the column Click.
                 A sorting will be done, but as I said it treats numbers  like strings, And couldn't find any place to change this behavior.
                ( If the control will do this sorting as part of it's default behavior so I don't need the custom sorter yet )
    What I have in the Designer Code :

    sortDescriptor1.PropertyName = "Column 0";
    sortDescriptor2.PropertyName = "Column 1";
    this.lvProd.SortDescriptors.AddRange(new Telerik.WinControls.Data.SortDescriptor[] {
    sortDescriptor1,
    sortDescriptor2});

    Third :
                For example, After a click of the user on a button we want to change our collection's order, How to find what is the
                current Sorting system
    (SortDescriptors ? ) on the ListView Control ?

    This is version 2011 Q2,
    Haven't the chance to update it yet, and the code was based on it.
  6. Robert
    Robert avatar
    10 posts
    Member since:
    Apr 2012

    Posted 22 Jul 2012 Link to this post

    Excuse me,
    Should I ask it in a new thread ?
    also pardon me for the unmarking of the answer, did this for the question to be reviewed as an active one.

    thanks for your previous information,
    still waiting to get the whole idea behind this
  7. Answer
    Ivan Todorov
    Admin
    Ivan Todorov avatar
    688 posts

    Posted 24 Jul 2012 Link to this post

    Hi Robert,

    You do not need to open new thread for each inquiry you have. New threads should be opened when your new questions are not related to the previous ones. This is not obligatory but usually lets us better track the cases and provide you with quicker responses. Also, when you write in a thread that was previously closed, it is automatically reopened and will be reviewed within the time corresponding to the type of the thread (support ticket, forum thread, etc.).

    As to the questions at hand, the name of a ListViewDetailColumn can only be given when it is being created. This is how RadListView is designed to operate in order to prevent conflicts of columns with the same name. You can give the columns a custom name if you are adding them programatically:
    this.radListView1.Columns.Add("ID");
    this.radListView1.Columns.Add("Name");
    this.radListView1.Columns.Add("Value");

    In regards to your question about the sort order, if you are populating the RadListView in Visual Studio's designer, the values you enter will be treated as strings. However, if you populate RadListView with the code that is shown below, you will see that the values in each column are sorted according to their type:
    this.radListView1.ViewType = ListViewType.DetailsView;
    this.radListView1.EnableColumnSort = true;
    this.radListView1.EnableSorting = true;
     
    this.radListView1.Columns.Add("ID");
    this.radListView1.Columns.Add("Name");
    this.radListView1.Columns.Add("Value");
     
    for (int i = 0; i <= 100; i++)
    {
        this.radListView1.Items.Add(i, "Name " + (i%30), ((i + 50) % 101) / 100.0);
    }

    As to your third question, you can get the current sort descriptors by using the RadListView.SortDescriptors collection. You can also modify this collection in order to set the sort order you desire. Note that if EnableSorting is false, the changes to this collection will have no effect. The following code demonstrates how to programatically sort RadListView ascending by the Name column and if there is a tie, descending by the Value column:
    this.radListView1.SortDescriptors.Add(new SortDescriptor("Name", ListSortDirection.Ascending));
    this.radListView1.SortDescriptors.Add(new SortDescriptor("Value", ListSortDirection.Descending));

    What the default sort comparer does when comparing two rows, is to traverse the SortDescriptors collection and compare the values in this columns specified by the current SortDescriptor. Comparison is done by trying to cast the records to IComparable and compare them. If this is not possible, they are compared as strings. The custom comparer I have posted in a previous message, has a similar functionality.

    I hope this will clarify how RadListView behaves. Do not hesitate to write back if you have any additional questions.

    Kind regards,
    Ivan Todorov
    the Telerik team
    RadControls for WinForms Q2'12 release is now live! Check out what's new or download a free trial >>
Back to Top
UI for WinForms is Visual Studio 2017 Ready