none
Natural numeric sort in listview controls RRS feed

  • Question

  • I found this article that shows you how to make a listview to sort by clicking the columns.
    I got it to work but found out that the column with numbers doesnt sort naturally.

    it becomes like this:

    1
    100
    2
    3
    6

    how do I make a natural sort. the article says to change a line, but I dont know what to change and to what

    this is the code the article told to change

    compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text);


    Thursday, November 8, 2007 2:51 PM

Answers

  • Use the Microsoft how to sort:

    http://support.microsoft.com/kb/319401

    Add some code to support numbers sort:

     

    /// <summary>
    /// This method is inherited from the IComparer interface.  It compares the two objects passed using a case insensitive comparison.
    /// </summary>
    /// <param name="x">First object to be compared</param>
    /// <param name="y">Second object to be compared</param>
    /// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
    public int Compare(object x, object y)
    {
    int compareResult;
    ListViewItem listviewX, listviewY;

    // Cast the objects to be compared to ListViewItem objects
    listviewX = (ListViewItem)x;
    listviewY = (ListViewItem)y;

    string xValue = listviewX.SubItems[ColumnToSort].Text;

    string yValue = listviewX.SubItems[ColumnToSort].Text,listviewY.SubItems[ColumnToSort].Text;

    double xNumber, yNumber;

    bool parsed = double.TryParse(xValue, out xNumber);

    parsed = parsed && double.TryParse(yValue, out yNumber);

    if(parsed)

    {

    compareResult = xNumber.Compare(yNumber); 

    }

    else

    {

    .... do the normal compare

    Friday, November 9, 2007 9:59 AM

All replies

  • this is sort on string instead of numeric value, try to implement the Compare function with int values.

    you can parse/convert the subitem text to int first.
    Thursday, November 8, 2007 3:20 PM
  • Are you talking about this Microsoft HowTo??

     

    http://support.microsoft.com/kb/319401/EN-US/

     

    Stefano Benedetti

    Thursday, November 8, 2007 3:22 PM
  • Replace that line with this:

     

    Code Block

    int valueX;

    int valueY;

    compareResult = ObjectCompare.Compare((int.TryParse(listviewX.SubItems[ColumnToSort].Text, out valueX) ? valueX : 0), (int.TryParse(listviewY.SubItems[ColumnToSort].Text, out valueY)? valueY : 0));

     

     

    Thursday, November 8, 2007 3:44 PM
  •  Be.St. wrote:

    Are you talking about this Microsoft HowTo??

     

    http://support.microsoft.com/kb/319401/EN-US/

     

    Stefano Benedetti

     

    ah, yes it is that one. forgot to attach a link >.<

     

     

    re: chris

    if i replace that line, will it work with both strings and numbers? it looks like it converts the string to int. i want it both way

    Friday, November 9, 2007 7:31 AM
  •  Daomen wrote:

    if i replace that line, will it work with both strings and numbers? it looks like it converts the string to int. i want it both way

     

    Do you want to use different listview:

    one showing numbers like
    10,

    23,

    42,

    100

     

    and others showing text like:

    a,

    bac,

    com,

    dom

     

    or do you want the possibility to compare string and numbers in a single listview like:

     

    10,

    23,

    100,

    a,

    bac

     

    ??

     

    The compare showed to you try to convert the value to an integer. If it fails compare 0.

    Friday, November 9, 2007 8:08 AM
  • the listview has columns that either are strings or numbers

    i want to sort alphabetic in those with strings and natural numeric in those with numbers
    Friday, November 9, 2007 8:12 AM
  • Use the Microsoft how to sort:

    http://support.microsoft.com/kb/319401

    Add some code to support numbers sort:

     

    /// <summary>
    /// This method is inherited from the IComparer interface.  It compares the two objects passed using a case insensitive comparison.
    /// </summary>
    /// <param name="x">First object to be compared</param>
    /// <param name="y">Second object to be compared</param>
    /// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
    public int Compare(object x, object y)
    {
    int compareResult;
    ListViewItem listviewX, listviewY;

    // Cast the objects to be compared to ListViewItem objects
    listviewX = (ListViewItem)x;
    listviewY = (ListViewItem)y;

    string xValue = listviewX.SubItems[ColumnToSort].Text;

    string yValue = listviewX.SubItems[ColumnToSort].Text,listviewY.SubItems[ColumnToSort].Text;

    double xNumber, yNumber;

    bool parsed = double.TryParse(xValue, out xNumber);

    parsed = parsed && double.TryParse(yValue, out yNumber);

    if(parsed)

    {

    compareResult = xNumber.Compare(yNumber); 

    }

    else

    {

    .... do the normal compare

    Friday, November 9, 2007 9:59 AM
  • thanks, with a little editing i got it to work
    Friday, November 9, 2007 11:48 AM
  • thanks, with a little editing i got it to work

    Tuesday, December 31, 2013 4:45 PM
  • Wai, do you mind sharing the editing you had to do to get this to work?

    Tuesday, December 31, 2013 4:46 PM
  • Wai, do you mind sharing the editing you had to do to get this to work?




    int xNumber = 0;
    int yNumber = 0;
    bool parsed = int.TryParse(xValue, out xNumber);
    
    parsed = parsed && int.TryParse(yValue, out yNumber);
    
    if (parsed)
    {
        compareResult = xNumber.CompareTo(yNumber);
    }
    else // ...













    bool parsed = int.TryParse(xValue, outxNumber);





    Thursday, June 16, 2016 5:37 PM