Dilip Nandakumar
Dilip Nandakumar

Reputation: 318

How to access a treeviewitem with in a treeviewitem in wpf?

I have populated my treeview using hierarchichal data template and using data template for sub menu items.

Here is what my xaml tree structure taken from wpf snoop looks like enter image description here

TreeViewItem item = (TreeViewItem)this.view.ItemContainerGenerator.ContainerFromIndex(0);

I am struggling to get the treeviewitems with in the parent treeviewitem (item).

I tried ItemContainerGenerator but the following returns null.

  TreeViewItem child = (TreeViewItem)item.ItemContainerGenerator.ContainerFromIndex(0);

As i traversed the treeviewitem using VisualTreeHelper.GetChild() method i ended up with a null return from ItemsPresenter that contains the child treeviewitems.

Is there any way i could access the child treeviewitems with in a treeviewitem ?

The xaml code of the template:

  <DataTemplate x:Key="Navigation_SubDataTemplate">
        <StackPanel Orientation="Horizontal">
            <ContentControl Focusable="False"  Background="{DynamicResource navigationlistboxfont}" Template="{Binding MenuTemplate}" Margin="5" Width="16" Height="16"/>
            <TextBlock Text="{Binding Path=MenuName}" ToolTip="{Binding ToolTip}" FontFamily="Segoe UI Light" FontSize="16" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </StackPanel>
    </DataTemplate>

    <HierarchicalDataTemplate x:Key="Navigation_DataTemplate" ItemsSource="{Binding SubMenuItems}" ItemTemplate="{StaticResource Navigation_SubDataTemplate}">
        <StackPanel Orientation="Horizontal">
            <ContentControl Focusable="False" Background="{DynamicResource navigationlistboxfont}" Template="{Binding MenuTemplate}" Margin="5" Width="20" Height="20"/>
            <TextBlock Margin="4,2" Text="{Binding Path=MenuName}" ToolTip="{Binding ToolTip}" FontFamily="Segoe UI Light" FontSize="16" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center">
            </TextBlock>
        </StackPanel>
    </HierarchicalDataTemplate>

And my treeview

<TreeView x:Name="MytreeView" helper:TreeViewExtension.SelectedItem="{Binding ViewSelected, Mode=TwoWay}"  ItemsSource="{Binding ViewMenuItems}" ItemTemplate="{DynamicResource Navigation_DataTemplate}"  Background="{x:Null}" BorderBrush="{x:Null}" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" Margin="0" ItemContainerStyle="{DynamicResource TreeViewItemStyle1}"  />

Here is my c# code of viewmenuitem used to bind to treeview

 List<ViewMenu> subMenus = new List<ViewMenu>();
 subMenus.Add(new ViewMenu() { MenuName = "Child1" });
 subMenus.Add(new ViewMenu() { MenuName = "Child2" });

 ViewMenuItems = new ObservableCollection<ViewMenu>();
 ViewMenuItems.Add(new ViewMenu() { MenuName = "Parent", SubMenuItems = subMenus });

Upvotes: 2

Views: 2258

Answers (2)

Luke Vanzweden
Luke Vanzweden

Reputation: 646

@Glen Thomas' answer works if your treeview's items are of type TreeViewItem. In my case, I was setting my treeview's source to be an XDocument. If you change the code to :

List<TreeViewItem> GetChildren(TreeViewItem parent)
{
    List<TreeViewItem> children = new List<TreeViewItem>();

    if (parent != null)
    {
        foreach (var item in parent.Items)
        {
            TreeViewItem child = item as TreeViewItem;

            if (child == null)
            {
                child = parent.ItemContainerGenerator.ContainerFromItem(parent) as TreeViewItem;
            }

            children.Add(child);
        }
    }

    return children;
}

It works to find any type of element. Before, it was:

            if (child == null)
            {
                child = parent.ItemContainerGenerator.ContainerFromItem(child) as TreeViewItem;
            }

which doesn't make sense, because if child is null, obviously ContainerFromItem(null) will return null, making child null.

Upvotes: 1

Glen Thomas
Glen Thomas

Reputation: 10744

The following method will retrieve all immediate child TreeViewItem objects of a TreeViewItem.

List<TreeViewItem> GetChildren(TreeViewItem parent)
{
    List<TreeViewItem> children = new List<TreeViewItem>();

    if (parent != null)
    {
        foreach (var item in parent.Items)
        {
            TreeViewItem child = item as TreeViewItem;

            if (child == null)
            {
                child = parent.ItemContainerGenerator.ContainerFromItem(child) as TreeViewItem;
            }

            children.Add(child);
        }
    }

    return children;
}

Upvotes: 1

Related Questions