Monday, April 25, 2011

Can I automatically wrap HierarchicalDataTemplate items inside of a TreeViewItem?

I have a 4-level tree structure, defined by:

<HierarchicalDataTemplate DataType="{x:Type src:Level1}" ItemsSource="{Binding Path=Level2Items}">
    <TextBlock Text="{Binding Path=Level1Name}"/>
</HierarchicalDataTemplate>

<HierarchicalDataTemplate DataType="{x:Type src:Level2}" ItemsSource="{Binding Path=Level3Items}">
    <TextBlock Text="{Binding Path=Level2Name}"/>
</HierarchicalDataTemplate>

<HierarchicalDataTemplate DataType="{x:Type src:Level3}" ItemsSource="{Binding Path=Level4Items}">
    <TextBlock Text="{Binding Path=Level3Name}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type src:Level4}">
    <TextBlock Text="{Binding Path=Level4Name}"/>
</DataTemplate>

And it works great. The only thing is, I can't programmatically select any of my bound items, because they're not of type TreeViewItem (and therefore don't have the "IsSelected" property). Is there a way to automatically wrap databound items in a particular container type (in this case: TreeViewItem)?

From stackoverflow
  • If your items are in a TreeView, they'll be wrapped in a TreeViewItem automatically by the TreeView's ItemContainerGenerator. You can do something like this to ensure the IsSelected property on TreeViewItem maps to a property on your data class:

    <TreeView>
        <TreeView.ItemContainerStyle>
            <Style TargetType="TreeViewItem">
                <Setter Property="IsSelected" Value="{Binding MyIsSelectedProperty}"/>
            </Style>
        </TreeView.ItemContainerStyle>
    </TreeView>
    

    HTH, Kent

    Pwninstein : Unfortunately, your assumption that bound items will be wrapped automatically inside a TreeViewItem isn't true in my case (for whatever reason). Calling GetType() on the first item in the TreeView's Items collection returns my type, not type "TreeViewItem". Any thoughts? Thanks!!
    Kent Boogaart : The Items collection contains your items as it is supposed to. The visual tree, however, wraps your item in a container. For TreeViews, the container is a TreeViewItem.
    KP Adrian : Kent is absolutely correct. Each item is wrapped in an ItemContainer, described by the ItemContainerStyle property. For a TreeView, the default container is a TreeViewItem. Check out Dr WPF's blog post on ItemContainers: http://drwpf.com/blog/Home/tabid/36/EntryID/32/Default.aspx
    Pwninstein : You're both right. The following code helps me accomplish what I'm trying to do: ((TreeViewItem)ConfigurationTreeView.ItemContainerGenerator.ContainerFromItem(myItem)).IsSelected = true; I'll just wrap that mechanism in to a helper function. Thanks again!!

0 comments:

Post a Comment