Quantcast
Viewing latest article 4
Browse Latest Browse All 8

WPF, MVVM and the TreeView Control using with different HierarchicalDataTemplates and DataTemplateSelector – Reloaded

In this previous post I outlined a way to work with the TreeView control in an MVVM fashion. In order to make any sense of this post you will need to refer to the previous one.

The code, in order to keep it simple, was quite verbose.

This post is really to outline a shorter, more generic, but more complex version of the hierarchy building code as per Listing 1 below.

public class HierarchyViewModel : ViewModelBase
{
    public CollectionView Customers { get; private set; }
    private HierarchyItemViewModel _selectedItem;

    public HierarchyViewModel(List customers, object selectedEntity)
    {
        var customerHierarchyItemsList = BuildHierarchyList<Customer>(customers, ((a, b) => a.Number == b.Number), selectedEntity,
            x => BuildHierarchyList<Order>(x.Orders, ((a, b) => a.Number == b.Number), selectedEntity,
                y => BuildHierarchyList<Product>(y.Products, ((a, b) => a.GetHashCode() == b.GetHashCode()), selectedEntity, null)
            )
        );

        this.Customers = new CollectionView(customerHierarchyItemsList);

        // select the selected item and expand it's parents
        if (_selectedItem != null)
        {
            _selectedItem.IsSelected = true;
            HierarchyItemViewModel current = _selectedItem.Parent;

            while (current != null)
            {
                current.IsExpanded = true;
                current = current.Parent;
            }
        }
    }

    private List<HierarchyItemViewModel> BuildHierarchyList<T>(List<T> sourceList, Func<T, T, bool> isSelected, object selectedEntity, Func<T, List<HierarchyItemViewModel>> getChildren)
    {
        List<HierarchyItemViewModel> result = new List<HierarchyItemViewModel>();

        foreach (T item in sourceList)
        {
            // create the hierarchy item and add to the list
            var hierarchyItem = new HierarchyItemViewModel(item);
            result.Add(hierarchyItem);

            // check if this is the selected item
            if (selectedEntity != null && selectedEntity.GetType() == typeof(T) && (isSelected.Invoke(item, (T)selectedEntity)))
            {
                _selectedItem = hierarchyItem;
            }

            if (getChildren != null)
            {
                var children = getChildren.Invoke(item);
                children.ForEach(x => x.Parent = hierarchyItem);
                hierarchyItem.Children = new CollectionView(children);
            }
        }

        return result;
    }
}

Listing 1

Final thoughts…

Comments are welcome on how to approve this further. My intention was to create a Type keyed dictionary of definitions that contained Func for finding the children and IComparers for deciding if the item is selected. This dictionary of definitions could then be passed in to the method that builds the tree which would make it even cleaner and better able to cope with changes in the hierarchy. However time prevented me from finalising this. Maybe later…

Downloads

WilberBeast.TreeView.Demo.zip (100.70 kb)
WilberBeast.TreeView.Demo.doc (100.70 kb)
Same as the zip version, just renamed to .doc to help with downloading.


Filed under: C#, MVVM, WPF Tagged: C#, DataTemplateSelector, Generics, HierarchicalDataTemplates, Hierarchy, MVVM, TreeView, WPF Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.

Viewing latest article 4
Browse Latest Browse All 8

Trending Articles