3
votes

I need to fill out a TreeView with a list of dictionaries that I have.

List<Dictionary<string,object>> 

Where the Dictionaries have title and children keys

[{"title":"foo", "children":[]},]

However I am unable to figure out the binding. This is completely wrong. I need obviously to display dict["title"] and use dict["children"] as the children.

<TreeView.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource="{Binding Value}">
       <HierarchicalDataTemplate.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}"/>
            </DataTemplate>
        </HierarchicalDataTemplate.ItemTemplate>
        <TextBlock Text="{Binding Key}"/>
    </HierarchicalDataTemplate>
</TreeView.ItemTemplate>

Hah so apparently Binding supports [] syntax so this sort of works:

        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Path=[children]}">
                <HierarchicalDataTemplate.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=[title]}"/>
                    </DataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>
                <TextBlock Text="{Binding Path=[title]}"/>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>

Each dictionary can have children nested to however many levels they want however. Is this possible to handle? With the above template and the following code the grand child is not displayed.

        string s = @"[{""title"":""Title1"",""children"":[{""title"":""Child1"",""children"":[{""title"":""grandchild1"",""children"":[]}]}]}]";

        List<Dictionary<string, object>> marr = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(s);
        mTreeView.ItemsSource = marr;

By the way using [] in the Binding is called indexers and I found out about it from the docs at this link:

http://msdn.microsoft.com/en-us/library/ms752300.aspx#Path_Syntax

1
You need a converter which can get/set values from a dictionary with a specific key. With such a converter you can do your binding along the lines of: {Binding Converter={StaticResource GetFromDictionaryConverter}, ConverterParameter=children} or {Binding Converter={StaticResource GetFromDictionaryConverter}, ConverterParameter=title}, assuming that the converter has been added as a resource with key GetFromDictionaryConverter and that it uses the converter parameter as the key and assumes that the binding source is a Dictionary. - odyss-jii

1 Answers

1
votes

Is this something that you are looking at:

<TreeView ItemsSource="{Binding ElementName=rootWindow, Path=Directories}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding [Children]}">
                <TextBlock Text="{Binding [Title]}" />
                <HierarchicalDataTemplate.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" />
                    </DataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

This is how i populate data:

Dictionary<string, object> documentsDictionary = new Dictionary<string, object>();
        List<string> documentsDictionaryChildren = new List<string> { "Document1", "Document2", "Document3", "Document4", "Document5" };
        documentsDictionary.Add("Title", "Documents");
        documentsDictionary.Add("Children", documentsDictionaryChildren);

        Dictionary<string, object> picturesDictionary = new Dictionary<string, object>();
        List<string> picturesDictionaryChildren = new List<string> { "Picture1", "Picture2", "Picture3", "Picture4", "Picture5" };
        picturesDictionary.Add("Title", "Pictures");
        picturesDictionary.Add("Children", picturesDictionaryChildren);

        Directories.Add(documentsDictionary);
        Directories.Add(picturesDictionary);