0
votes

I have a custom comparer I want to use with OrderBy. This comparer enables to sort nested lists the way I want. I perfectly works somewhere else, but I can't make it work the way I want with Linq. Can you tell me where I'm wrong?

EDIT : the way I want to make it work is to group my entities first by class (BaseDirectory > BaseSite > VideoEntity, always), then sort them alphabetically (ascending = A->Z, or descending Z->A). Anyway when I use SortDirectoriesDescending(), I'm returned the collection sorted in ascending. By default the collection is sorted in ascending mode (so the converter works, and I've tested it for descending, OK too)

public class VideoEntityComparer : IComparer<VideoEntity>
{

    int order = 1;

    public VideoEntityComparer(Boolean ascending)
    {
        if (!ascending)
        {
            this.order = -1; // so descending
        }
    }

    public VideoEntityComparer()
    {

    }

    public int Compare(VideoEntity x, VideoEntity y)
    {
        if ((x is BaseDirectory && y is BaseDirectory) || (x is BaseSite && y is BaseSite) || (x is VideoEncoder && y is VideoEncoder))
        {
            return string.Compare(x.Nom, y.Nom, false) * order; // only objects of the same type are sorted alphabetically
        }
        else if ((x is BaseDirectory && y is BaseSite) || (x is BaseSite && y is VideoEncoder))
        {
            return -1;
        }else
        {
            return 1;
        }
    }
}

private void SortDirectoriesDescending(object sender, RoutedEventArgs e)
    {
        ObservableCollection<BaseDirectory> tempDir  = new ObservableCollection<BaseDirectory>(
            Directories.OrderBy(directory => directory, new VideoEntityComparer(false)));
        Directories = tempDir;
    }
1
Define "the way you want". It'll be key to the answer I think. Is the problem in the implementation of the comparer or plugging it into the OrderBy method? The call to OrderBy looks correct.Adam Houldsworth
I've just defined "the way I want" in the edit ;)Sheamus
Since your SortDirectoriesDescending method is replacing the Directories collection with a new sorted collection, rather than sorting in-place, if you have taken the value of "Directories" before calling the sort method, you will not see the new sort order. You may need to provide some more code (specifically any code that uses "Directories" and the section of code where SortDirectoriesDescending is called) to determine the problem, because as it is, everything looks fine.Iridium

1 Answers

1
votes

Try making the following change to your compare method:

public int Compare(VideoEntity x, VideoEntity y)
{
    if ((x is BaseDirectory && y is BaseDirectory) || (x is BaseSite && y is BaseSite) || (x is VideoEncoder && y is VideoEncoder))
    {
        return string.Compare(x.Nom, y.Nom, false) * order; // only objects of the same type are sorted alphabetically
    }
    else if ((x is BaseDirectory && y is BaseSite) || (x is BaseSite && y is VideoEncoder) || (x is BaseDirectory && y is VideoEncoder)) // Added (x is BaseDirectory && y is VideoEncoder)
    {
        return -1;
    }
    else
    {
        return 1;
    }
}

Your code previously was defining an order BaseDirectory < BaseSite, and BaseSite < VideoEncoder, but BaseDirectory > VideoEncoder, which seems likely to confuse OrderBy since your ordering is not transitive.