Sort nodes of a TreeView

819 views Asked by At

I am using the telerik RadTreeView to show a hierarchy of folders. The user must be able to add/remove/rename folders in this tree. This works so far but the tree should be alphabetically sorted each time the tree is changed.

To sort the TreeView I am supposed to sort the underlying data model. This means the top level folders and recursively all children.

My underlying model is stored in a database and accessed using EF. It is basically an Entity "TreeFolder" with a 1:n association to itself. EF lets me access the child folders of a TreeFolder as EntityCollection.

My problem here is: How can I sort the EntityCollections? So far I know this is not possible - I should use a wrapper like a CollectionViewSource. This would mean I would need to create a new class "SortableTreeFolder" (or extend the partial class from EF) which holds such a CollectionViewSource. This means I would need to copy all children into this CollectionViewSource when the tree is loaded.

Is there a possibility to sort the TreeView model only using the EF navigation properties?

EDIT: After trying out different things (thanks Uwy) I as well stumbled across this site: Sorting EF Collection

There it says:

Although EntityCollection doesn't implement IList, it implements IListSource and CollectionViewSource will call IListSource.GetList method to create the view. EntityCollection.GetList will actually return an IBindingList object that doesn't support sort. As a result, the collection view of the EntityCollection doesn't support sorting by default.

Obviously it is not possible to sort the TreeView model only using the EF navigation properties. I am still looking for a workaround besides managing a second (sortable) data structure.

1

There are 1 answers

5
Uwy On

(From my previous comments)

By default, WPF item source bindings fallbacks to what CollectionViewSource.GetDefaultView() gives (at least when it's on the same thread). You could try doing that recursively on your entities, adding a sort description.

public class MainWindowViewModel
{

    public void SetupCollectionView(IEnumerable<MyObject> entities)
    {
        foreach(var entity in entities)
        {
            CollectionViewSource.GetDefaultView(entity)
                .SortDescriptions.Add(new SortDescription(nameof(MyObject.Header), ListSortDirection.Ascending));
            this.SetupCollectionView(entity.Childs);
        }
    }
}

public class MyObject
{
    public string Header { get; set; }
    public int AnotherProperty { get; set; }

    public virtual IEnumerable<MyObject> Childs { get; set; }
}