#1,215 – Binding a TreeView to a Hierarchical Data Source

Below is a very simple example of how you might use a TreeView control to display a set of hierarchical data.

Let’s say that we have a Person object that looks like the following. (INPCBase is just a class that implements INotifyPropertyChanged and includes a SetField method).

    public class Person : INPCBase
    {
        public Person(string name, int birth, int? death)
        {
            Name = name;
            Birth = birth;
            Death = death;

            Children = new List<Person>();
        }

        private string _name;
        public string Name
        {
            get { return _name; }
            set { SetField(ref _name, value); }
        }

        private int _birth;
        public int Birth
        {
            get { return _birth; }
            set { SetField(ref _birth, value); }
        }

        private int? _death;
        public int? Death
        {
            get { return _death; }
            set { SetField(ref _death, value); }
        }

        private List<Person> _children;
        public List<Person> Children
        {
            get { return _children; }
            private set { SetField(ref _children, value); }
        }

        public override string ToString()
        {
            string death = Death.HasValue ? Death.Value.ToString() : "";
            return string.Format($"{Name} ({Birth} - {death})");
        }
    }

Notice that we have a Children property that in turn contains other Person objects. Also note that we override ToString so that the default string representation for a Person includes their name and birth/death.

Now let’s assume that we have some ViewModel with a property called Royal that is a list of Person objects. The property might look like:

        private List<Person> _royal;
        public List<Person> Royal
        {
            get { return _royal; }
            set { SetField(ref _royal, value); }
        }

Let’s assume that we initialize this list as follows:

            var p1 = new Person("George V", 1865, 1936);

            var p2 = new Person("Edward VIII", 1894, 1974);
            var p3 = new Person("George VI", 1895, 1952);
            var p4 = new Person("Mary", 1897, 1965);
            var p5 = new Person("Henry", 1900, 1974);
            var p6 = new Person("George", 1902, 1942);
            var p7 = new Person("John", 1905, 1919);

            var p8 = new Person("Elizabeth II", 1926, null);
            var p9 = new Person("Margaret", 1865, 1936);

            var p10 = new Person("Richard", 1944, null);

            var p11 = new Person("Edward", 1935, null);
            var p12 = new Person("Michael", 1942, null);

            var p13 = new Person("Charles", 1948, null);
            var p14 = new Person("Anne", 1950, null);
            var p15 = new Person("Andrew", 1960, null);
            var p16 = new Person("Edward", 1964, null);

            p1.Children.AddRange(new [] { p2, p3, p4, p5, p6, p7});
            p3.Children.AddRange(new[] { p8, p9 });
            p5.Children.Add(p10);
            p6.Children.AddRange(new[] { p11, p12 });
            p8.Children.AddRange(new[] { p13, p14, p15, p16 });

            Royal = new List<Person>() { p1 };

To wire this hierarchical data source up to a TreeView control, we use a HierarchicalDataTemplate in XAML, as shown below.

        <TreeView Grid.Row="0" Margin="5" ItemsSource="{Binding Royal}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                    <TreeViewItem Header="{Binding}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

There are several things to note about this XAML fragment:

  • We set the ItemsSource of the TreeView to our top-level property (a list of Person, which contains one person).
  • We tell the HierarchicalDataTemplate to use the Children property to traverse the hierarchy
  • We indicate that each node should be a TreeViewItem object, with text (Header) that just binds to the Person object. This causes the default ToString method of the object to be used for the text

The final result is a nice little family tree:

1215-01

About Sean
Software developer in the Twin Cities area, passionate about software development and sailing.

3 Responses to #1,215 – Binding a TreeView to a Hierarchical Data Source

  1. Pingback: Dew Drop - August 31, 2017 (#2552) - Morning Dew

  2. Patricia says:

    Great tutorial. Not able to figure out how you create the methoed: SetField

Leave a comment