1

The Scenario

I want to create a ListView which functions like the Windows Explorer "Details" view. Items should be sortable by columns, with the following rules:

  • Sorting by name should place folders first.
  • Sorting by date modified should place files first.

 

The Code

private string _lastSortBy = "FullName";
private ListSortDirection? _lastSortDirection = ListSortDirection.Ascending;

private void Sort(string sortBy = null, ListSortDirection? direction = null)
{
    if (sortBy == null)
        sortBy = _lastSortBy;

    _lastSortBy = sortBy;

    if (direction == null)
        direction = _lastSortDirection;

    _lastSortDirection = direction;

    ICollectionView dataView = CollectionViewSource.GetDefaultView(listView.ItemsSource);

    dataView.SortDescriptions.Clear();

    SortDescription sd = new SortDescription(sortBy, direction.Value);
    dataView.SortDescriptions.Add(sd);

    dataView.GroupDescriptions.Clear();

    PropertyGroupDescription pgd = new PropertyGroupDescription("FileSystemItemType");
    dataView.GroupDescriptions.Add(pgd);

    dataView.Refresh();
}

 

The Problem

This function works beautifully - except for one glitch. When sorting by name, if the first file's name is alphabetically prior to the first folder's name, the files group is displayed before the folders group. If the first folder's name is alphabetically prior to the first file's name, however, the folders group is displayed before the files group.

I know the previous paragraph is confusing, so let me simplify.

Files before folders

a.txt       file
b.txt       file
c.txt       file
b           folder
c           folder
d           folder

 

Folders before files

a           folder
b           folder
c           folder
b.txt       file
c.txt       file
d.txt       file

 

The Question

Is it possible to control the display order of groups, without relying on the default sort mechanism?

1 Answer 1

4

One solution would be to use multiple SortDescription when sorting by name. For example sort first by FileSystemItemType, which should put folders first, and then by name. Or, if your source is an IList instead of using ICollectionView you could cast it to ListCollectionView

var lcv = (ListCollectionView)CollectionViewSource.GetDefaultView(listView.ItemsSource);
lcv.CustomSort = new CustomComparer();

it allows you to define custom IComparer by setting CustomSort property

public class CustomComparer : IComparer  
{
    public int Compare(Object x, Object y)  
    {
        //implement custom rules in here
    }
}

and this in turn lets you define any custom sorting rule

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.