Search code examples
c#sortingdelegatescompareicomparable

How to specify multiple sort methods in Compare?


I'm working on sorting data by name, size and date. I managed to sort them by name but i'm not quite sure on how to implement multiple compare methods in my class. I tried taking a look at using delegates, couldn't really understand how they work exactly. Here's what I got so far

 private List<data> _myList = new List<data>();
 private bool sortAsc = false;

public class data
{
    public string Name { get; set; }
    public string Size { get; set; }
    public string Date { get; set; }
    public bool flag { get; set; }
}

 private void GridViewColumnHeader_Name(object sender, RoutedEventArgs e)
 {
     sortAsc = !sortAsc;
     if (sortAsc)
        _myList.Sort(new ListViewColumnSorterAsc());
     else
        _myList.Sort(new ListViewColumnSorterDesc());

        //------------------

     listView.Items.Clear();
     foreach (var item in _myList)
        listView.Items.Add(item);
}

public class ListViewColumnSorterAsc : IComparer<data>
{
    public int Compare(data x, data y)
    {
        if (x.flag == y.flag)
        {
            if (x.Name.CompareTo(y.Name) == 0)
                return 0;
            else if (x.Name.CompareTo(y.Name) == 1)
                return 1;
            else
                return -1;
        }

        else if (x.flag)
        {
            return -1;
        }

        return 0;
    }
}

//------- What I had in mind was to create a constructor in "ListViewColumnSorterAsc" and pass an ENUM to it to identify how I want the sort to happen and then pass that as an argument to Compare method in the class

public enum Sorting_Mode
{
    by_Name = 1,
    by_Size = 2,
    by_Date = 3
}; 

public class ListViewColumnSorterAsc : IComparer<data>
{
    private Sorting_Mode srtMode;

    public ListViewColumnSorterAsc(Sorting_Mode srtMode)
    {
        this.srtMode = srtMode;

        if(srtMode == Sorting_Mode.by_Size)
        {
            // i'm not quite sure what to set here and how to pass it
            // to Compare
        }

        if(srtMode == Sorting_Mode.by_Name)
        {

        }

        if(srtMode == Sorting_Mode.by_Date)
        {

        }
    }

    public int Compare(data x, data y)
    {
         // i want to use the same code as the above except it should be 
         // object1.compareType.CompareTo(object2.compareType)  
    }

i'm almost sure the solution is using delegates, so could someone plz explain how they are used. I read the page on MSDN about delegate it was complicated


Solution

  • I don't see a need for delegates: in the class constructor, all you need to do is to store the sort mode parameter, then in the Compare method you use it. So:

    public class ListViewColumnSorterAsc : IComparer<data>
    {
        private Sorting_Mode srtMode;
    
        public ListViewColumnSorterAsc(Sorting_Mode srtMode) 
        {
            this.srtMode = srtMode;
        }
    
        public int Compare(data x, data y) 
        {
            switch (srtMode) {
                case Sorting_Mode.by_Name:
                    return x.Name.CompareTo(y.Name);
                case Sorting_Mode.by_Size:
                    return x.Size.CompareTo(y.Size);
                case Sorting_Mode.by_Date:
                    return x.Date.CompareTo(y.Date);
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    }