1
votes

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 });
2
I may be wrong, but your issue could be caused by UI virtualization. Try expanding the tree until you see the node you're trying to get hold of, and then apply your methods to retrieve the TreeViewItem. If it works at that point, then it's most likely the cause. Alternatively, you could try setting VirtualizingPanel.IsVirtualizing="False" on your TreeView.Grx70
please, show code of populating your TreeView and HierarchicalDataTemplate.StepUp
@StepUp I have added my xaml of treeview and templates.Dilip Nandakumar
and C# code of populating of TreeViewStepUp
added c# code of my vmDilip Nandakumar

2 Answers

1
votes

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;
}
0
votes

@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.