HypernovaDesktop Components · docs
Binarymission
WPF › Tree List View

Tree List View

.NET Framework 4.8.NET 6 / 8 / 10v3.0.0WPF

A tree and a grid in one control: rows that nest, expand and collapse like a TreeView, laid out in resizable, sortable, reorderable columns like a ListView in grid view.

9public types
150public members
2namespaces

Assembly

AssemblyBinarymission.WPF.Controls.BinaryTreeListView.dll
Root namespaceBinarymission.WPF.Controls.TreeControls
Target frameworks.NET Framework 4.8, .NET 6 / 8 / 10
Depends onSkinning

Overview

Use it wherever data has both a hierarchy and several facts per row: a project plan with owners and dates, a file system with sizes and types, a chart of accounts with balances, an organisation with roles and locations.

Columns

Add a GridViewColumn to Columns for each column, exactly as for a GridView: give it a GridViewColumn.DisplayMemberBinding for plain text, or a GridViewColumn.CellTemplate for anything richer. One column carries the tree – the indent, the expander and the connecting lines. It is the first column unless you choose another with TreeListViewColumnIndex or TreeListViewColumn. The rows line up across every level of the tree, and follow the headings when the user resizes or drags them.

Rows

There are two ways to give the control its rows, and every feature works with both.

Sorting

With AllowsColumnSorting on, a click on a heading sorts by that column and a second click reverses it; SortByColumn and ClearColumnSort do the same from code. Each branch is sorted within itself, so children stay under their parents. A column that draws its cells with a template has no binding to sort by – name the property with SetSortMemberPath.

Selection

Single selection works as in any tree view, through TreeView.SelectedItem and TreeView.SelectedItemChanged. Turn on IsMultiSelectionEnabled to let Ctrl+click add and remove rows, and IsShiftMultiSelectionEnabled as well to let Shift+click select every row on show between the last row clicked and this one, at any depth. The rows selected that way are in MultiSelectedItems.

Appearance

Theme applies one of eight built-in colour schemes in a single setting, and any brush can then be set on its own to depart from it. Alternate-row striping (AlternateRowBackgroundBrush) counts the rows as they are drawn, so it stays correct as branches open, close and sort. The expander can be drawn in five shapes (ExpanderGlyph), the connecting lines solid or dotted, and the column headings in colours of your own. The default colour given for each brush is the one used with no Binarymission skin in force; a skin (Binarymission.WPF.Skinning) supplies its own.

Getting started

A bound tree of folders and files in XAML. Each FolderRow has Name, Kind, Size and Modified properties and a Children collection; the window's data context exposes the top-level rows as Roots.

<Window x:Class="Explorer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:tlv="clr-namespace:Binarymission.WPF.Controls.TreeControls;assembly=Binarymission.WPF.Controls.BinaryTreeListView"
        Title="Explorer" Width="900" Height="560">

    <tlv:BinaryTreeListView ItemsSource="{Binding Roots}"
                            TreeListViewColumnIndex="0"
                            AllowsColumnSorting="True"
                            AllowsColumnReorder="True"
                            IsMultiSelectionEnabled="True"
                            IsShiftMultiSelectionEnabled="True"
                            ExpanderGlyph="Chevron"
                            Theme="Office">

        <tlv:BinaryTreeListView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Children}" />
        </tlv:BinaryTreeListView.ItemTemplate>

        <tlv:BinaryTreeListView.Columns>
            <GridViewColumn Header="Name"     Width="320" DisplayMemberBinding="{Binding Name}" />
            <GridViewColumn Header="Type"     Width="140" DisplayMemberBinding="{Binding Kind}" />
            <GridViewColumn Header="Size"     Width="100" DisplayMemberBinding="{Binding Size, StringFormat={}{0:N0} KB}" />
            <GridViewColumn Header="Modified" Width="160" DisplayMemberBinding="{Binding Modified, StringFormat=d}" />
        </tlv:BinaryTreeListView.Columns>
    </tlv:BinaryTreeListView>
</Window>

The same control built in code, with the rows added as nodes rather than bound. The row objects can be any class with public properties.

using System.Windows.Controls;
using System.Windows.Data;
using Binarymission.WPF.Controls.TreeControls;

public sealed class TaskRow
{
    public string Name { get; set; }
    public string Owner { get; set; }
    public int Percent { get; set; }
}

BinaryTreeListView plan = new BinaryTreeListView
{
    AllowsColumnSorting = true,
    IsMultiSelectionEnabled = true,
    Theme = BinaryTreeListViewTheme.Office
};

plan.Columns.Add(new GridViewColumn { Header = "Task",  Width = 280, DisplayMemberBinding = new Binding("Name") });
plan.Columns.Add(new GridViewColumn { Header = "Owner", Width = 140, DisplayMemberBinding = new Binding("Owner") });
plan.Columns.Add(new GridViewColumn { Header = "Done",  Width = 80,  DisplayMemberBinding = new Binding("Percent") { StringFormat = "{0}%" } });
plan.TreeListViewColumnIndex = 0;

BinaryTreeListViewItem design = new BinaryTreeListViewItem
{
    Header = new TaskRow { Name = "Design", Owner = "Priya", Percent = 60 },
    IsExpanded = true
};
design.Items.Add(new BinaryTreeListViewItem { Header = new TaskRow { Name = "Wireframes", Owner = "Priya", Percent = 100 } });
design.Items.Add(new BinaryTreeListViewItem { Header = new TaskRow { Name = "Visual design", Owner = "Tom", Percent = 20 } });

plan.Items.Add(design);

API reference

Binarymission.WPF.Controls.TreeControls

class BinaryCheckBoxA check box whose box, border and check mark can each be coloured for every state - normal, pointer over, pressed and disabled - without writing a template.
class BinaryTreeListViewA tree and a grid in one control: rows that nest, expand and collapse like a TreeView, laid out in resizable, sortable, reorderable columns like a ListView in grid view.
enum BinaryTreeListViewExpanderGlyphThe shapes the expand / collapse control can be drawn as.
class BinaryTreeListViewItemOne row of a BinaryTreeListView: its cells, its expander and the rows beneath it.
enum BinaryTreeListViewThemeThe built-in colour schemes a BinaryTreeListView can draw itself in.

Binarymission.WPF.Controls.TreeControls.Converters

class BinaryTreeListConnectingLineConverterTells a row's template whether the row is the last of its siblings, which is where a connecting line stops rather than carrying on down.
class BinaryTreeListConnectingRootLineConverterTells a row's template whether the row is a top-level row, which has no parent to draw a line up to.
class BooleanToCornerRadiusConverterTurns a bool into a CornerRadius, so a switch in the control can round a border the template draws.
class PathToImageSourceConverterTurns an image's address - a file path, a pack URI or a web address, as a string or a Uri - into an ImageSource, so a row object can name its icon as text.