none
Custom sorting order for ListBox and/or IComparable RRS feed

  • Question

  • Hi all,

    I am trying to override a ListBox's sorting function to sort items in a non-alphanumeric order.

    The ListBox is being populated with a list of development projects' folder names, with the naming convention of CompanyName.ProjectName.DevelopmentPhase, from which users can select environments to install.

    For example:

    • MyCompany.Project1.PRD
    • MyCompany.Project1.UAT
    • MyCompany.Project1.TST1
    • MyCompany.Project1.TST2
    • MyCompany.Project1.DEV

    I want to change the ListBox so that enabling its Sorted property will sort it in the above order: PRD, UAT, TST, DEV, and then alphanumerically after that.

    As I am populating this from a collection of the object class DevelopmentProject, I was wondering if there was (also) a way to implement IComparable<DevelopmentProject>'s CompareTo to sort the collection in this way.

    My DevelopmentProject Class is below, with its collection and the ListBox populated by:

    string[] projectFolders = Directory.GetDirectories("\\server\developmentprojects");
    
    public List<DevelopmentProject> DevelopmentProjects
    {
       return new List<DevelopmentProject>(
          from subfolder in projectFolders
          where ...
          select new DevelopmentProject(subfolder));
    }
    
    ...
    
    DevelopmentProjects.ForEach(x => listBox1.Items.Add(x.Name));


    class DevelopmentProject : IComparable<DevelopmentProject>
    {
       public string Name
       {
          get {return Path.GetFileName(Location); }
       }
    
       private string Location { get; set; };
    
       public string Phase
       {
          // I am cheating by treating the development phase as a file extension
          get { return Path.GetExtension(Location).Substring(1); }
       }
    
       public DevelopmentProject(string location)
       {
          Location = location;
       }
    
       public int CompareTo(DevelopmentProject project)
       {
          //unsure what to do here to sort by Phase in the order or PRD, UAT, TST, DEV, and alphanumerically after
       }
    }


    Any direction as to how I can achieve this for the ListBox and Class's sorting is greatly appreciated.

    Thanks,

    Thomas


    Saturday, March 2, 2019 10:45 AM

Answers

  • Check this:

    List<string> Phases = new List<string> { "PRD", "UAT", "TST1", "TST2", "DEV" };
    
    public int CompareTo( DevelopmentProject project )
    {
        var n1 = Phases.IndexOf( Phase.ToUpper() );
        var n2 = Phases.IndexOf( project.Phase.ToUpper() );
    
        if( n1 < 0 )
        {
            if( n2 < 0 )
            {
                return string.Compare( Phase, project.Phase, true );
            }
    
            return +1;
        }
    
        if( n2 < 0 ) return -1;
    
        return n1 - n2;
    }
    
    

    Sorting and adding the items:

    DevelopmentProjects
       .OrderBy( p => p )
       .ToList()
       .ForEach( p => listBox1.Items.Add( p ) );
    listBox1.DisplayMember = "Name";


    Saturday, March 2, 2019 2:20 PM

All replies

  • Hello,

    > //unsure what to do here to sort

    Nothing need to be done here to sort.

    Here you compare two DevelopmentProject and return:

    -1 - if current item supposed to be before given

    0 - if on the same position

    +1 - if after.

    Just a compare - sort will use this interface method to determine order of elements. 


    Sincerely, Highly skilled coding monkey.

    Saturday, March 2, 2019 11:07 AM
  • Hi Andrey,

    The comparisons performed by CompareTo are still alphabetical, whether ascending or descending.

    The only advantage is that I can select specific properties of a class to sort alphanumerically by, which isn't what I am trying to achieve. 

    I want to arrange a ListBox and List so that it is in the order of:

    • PRD
    • UAT
    • TST
    • DEV

    For the ListBox, this ensures that when Sorted = true, it will rearrange in that order instead of alphanumerically.

    Then only way I can presently think of for the class is creating another property with a sort code, and sorting by two objects' sort code before  sorting alphanumerically by the objects' name or another property.

    I am still at a loss about the ListBox though. 
    Saturday, March 2, 2019 2:17 PM
  • Check this:

    List<string> Phases = new List<string> { "PRD", "UAT", "TST1", "TST2", "DEV" };
    
    public int CompareTo( DevelopmentProject project )
    {
        var n1 = Phases.IndexOf( Phase.ToUpper() );
        var n2 = Phases.IndexOf( project.Phase.ToUpper() );
    
        if( n1 < 0 )
        {
            if( n2 < 0 )
            {
                return string.Compare( Phase, project.Phase, true );
            }
    
            return +1;
        }
    
        if( n2 < 0 ) return -1;
    
        return n1 - n2;
    }
    
    

    Sorting and adding the items:

    DevelopmentProjects
       .OrderBy( p => p )
       .ToList()
       .ForEach( p => listBox1.Items.Add( p ) );
    listBox1.DisplayMember = "Name";


    Saturday, March 2, 2019 2:20 PM
  • Thank you!!

    This is brilliant!

    Sunday, March 3, 2019 9:37 AM