rreeves
rreeves

Reputation: 2458

WPF Treeview Bindings

I'm trying to bind an ObservableCollection to a treeview in WPF. It does kind-of work but not quite the way I thought it would.

This is the binding I have setup

    <TreeView Height="250" ItemsSource="{Binding Path=TheUsers}" VerticalAlignment="Bottom" Width="500" Margin="0,39,0,0">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Path=Permission}">
                <TextBlock Text="{Binding}" />
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView> 

This is the collection it is binding to:

    ObservableCollection<UserViewModel> theUsers;
    public ObservableCollection<UserViewModel> TheUsers
    {
        get
        {
            return theUsers;
        }
        set
        {
            theUsers = value;
            OnPropertyChanged("TheUsers");
        }
    }

This is the object in the collection:

public class UserViewModel
{     
    string userName = null;
    public string UserName
    {
        get
        {
            return userName;
        }
        set
        {
            userName = value;
            OnPropertyChanged("UserName");
        }
    }

    int permCount = 0;
    public int PermCount
    {
        get
        {
            return permCount;
        }
        set
        {
            permCount = value;
            OnPropertyChanged("PermCount");
        }
    }

    List<string> permission = null;
    public List<string> Permission
    {
        get
        {
            return permission;
        }
        set
        {
            permission = value;
            OnPropertyChanged("Permission");
        }
    }

This is what it displays

screenshot

What I would like it to do is display the UserName for UserViewModel and the Permissions List<string> items as the children. What is the proper way to do this ?

Thanks in Advance!

Upvotes: 2

Views: 2680

Answers (3)

ChrisWue
ChrisWue

Reputation: 19020

You should be able to do this with a HierarchicalDataTemplate in addition to a normal DataTemplate:

<TreeView Height="250" ItemsSource="{Binding Path=TheUsers}" VerticalAlignment="Bottom" Width="500" Margin="0,39,0,0">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:UserViewModel}" ItemsSource="{Binding Permission}">
            <TextBlock Text="{Binding Path=UserName}" />
        </HierarchicalDataTemplate>
        <DataTemplate DataType="{x:Type sys:String}" >
            <TextBlock Text="{Binding}" />
        </DataTemplate>
    </TreeView.Resources>
</TreeView> 

Add the following namespaces to your control/window:

xmlns:local="clr-namespace:WhateverYourAssemblyNamespaceIs"
xmlns:sys="clr-namespace:System;assembly=mscorlib"

Upvotes: 1

Luke Woodward
Luke Woodward

Reputation: 64949

With a bit of help from the MSDN DataTemplating overview, I think the following will do what you want. Note that I've added a top-level 'All Users' item to the treeview:

<Window.Resources>
    <HierarchicalDataTemplate DataType="{x:Type local:UserViewModel}" ItemsSource="{Binding Path=Permission}">
        <TextBlock Text="{Binding Path=UserName}"/>
    </HierarchicalDataTemplate>
    <DataTemplate DataType="{x:Type sys:String}">
        <TextBlock Text="{Binding}"/>
    </DataTemplate>
</Window.Resources>

...

<TreeView Height="250" VerticalAlignment="Bottom" Width="500" Margin="0,39,0,0">
    <TreeViewItem ItemsSource="{Binding Path=TheUsers}" Header="All Users" />
</TreeView>

Replace the prefix local with a namespace prefix bound to the namespace your UserViewModel class lives in.

You can set IsExpanded="True" on the <TreeViewItem> if you want the treeview to appear with the All Users item expanded.

Note that I used an ordinary DataTemplate for the permissions, because I don't think you want the treeview to expand any further beyond a permission. (The tree could expand, because permissions are strings, and strings implement IEnumerable<char>. If you tried to expand a string, you'd get a list of the individual characters of the string.)

Upvotes: 0

dwonisch
dwonisch

Reputation: 5785

Use a HierarchicalDataTemplate like

<TreeView.Resources>
    <HierarchicalDataTemplate  DataType="{x:Type local:UserViewModel}" ItemsSource="{Binding Permission}" >
        <TextBlock Text="{Binding UserName}"/>
    </HierarchicalDataTemplate>
</TreeView.Resources>  

Upvotes: 2

Related Questions