Search code examples
c#wpfdata-binding

WPF TreeView - what element type should my ObservableCollection be to bind it to its DataSource?


MVVM style. Wihtout messing with the view too much, preferably - without touching the view.

Is it possible to create a collection that will just contain the nested items and the TreeView would just display them?

I've seen an example with a MenuItem used as the data type. What if I don't want to use MenuItem? I assume, my item should just implement an interface that defines how it can contain other items. What is this interface?

Also - I need to have a checkbox on each item, but that's probably a matter of providing the item template.

Then again, a MenuItem can be checked, that might be useful ;)


Solution

  • The beauty of the ItemsControl classes in WPF (including ListBox and TreeView) is that the items source can be a collection of any type you like. There's no reason why it has has to be a UI based class - in fact with templates, it probably should never should be.

    You then set the ItemTemplate to define what UI is displayed for each item in the ItemsSource collection.

    e.g.

    public class Person
    {
        public string FirstName {get;set;}
        public string LastName {get;set;}
        public List<Person> Children {get;} = new List<Person>();
    }
    
    
    public class MainViewModel
    {
        public List<Person> PersonList {get;} = new List<Person>();
    } 
    
    
    
    <TreeView
        ItemsSource = {Binding PersonList} >
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate
                ItemsSource="{Binding Children}">
                <StackPanel>
                    <Textblock Text={Binding FirstName} />
                    <Textblock Text={Binding LastNameName} />
                </StackPanel>
            </HierarchicalDataTemplate>
        <TreeView.ItemTemplate>
    </TreeView>
    

    Take a look at my blog post for a deeper discussion on how to handle TreeView controls in a MVVM context.