如何在 wpf 中的 treeviewitem 中访问 treeviewitem?

Posted

技术标签:

【中文标题】如何在 wpf 中的 treeviewitem 中访问 treeviewitem?【英文标题】:How to access a treeviewitem with in a treeviewitem in wpf? 【发布时间】:2016-08-23 07:17:15 【问题描述】:

我已经使用分层数据模板和子菜单项的数据模板填充了我的树视图。

这是我从 wpf snoop 获取的 xaml 树结构的样子

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

我正在努力在父树视图项(项目)中获取树视图项。

我尝试了 ItemContainerGenerator 但以下返回 null。

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

当我使用 VisualTreeHelper.GetChild() 方法遍历树视图项时,我最终从包含子树视图项的 ItemsPresenter 返回空值。

有什么方法可以在 treeviewitem 中访问子 treeviewitem 吗?

模板的xaml代码:

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

还有我的树视图

<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"  />

这是我用于绑定树视图的 viewmenuitem 的 c# 代码

 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 );

【问题讨论】:

我可能错了,但您的问题可能是由 UI 虚拟化引起的。尝试展开树,直到您看到要获取的节点,然后应用您的方法检索TreeViewItem。如果它在那个时候起作用,那么它很可能是原因。或者,您可以尝试在您的TreeView 上设置VirtualizingPanel.IsVirtualizing="False" 请显示填充 TreeView 和 HierarchicalDataTemplate 的代码。 @StepUp 我已经添加了我的树视图和模板的 xaml。 TreeView的填充C#代码 添加了我的虚拟机的c#代码 【参考方案1】:

以下方法将检索 TreeViewItem 的所有直接子 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;

【讨论】:

使用 ItemContainerGenerator 铸造项目都返回 null。 parent.items 中的对象是什么类型的? 类型是 ViewMenu。我创建的自定义类。包括在上面。 @DilipNandakumar 请参阅下面的答案【参考方案2】:

@Glen Thomas 的回答有效,如果您的树视图的项目是 TreeViewItem 类型。就我而言,我将树视图的源设置为 XDocument。如果您将代码更改为:

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;

它可以找到任何类型的元素。 之前是:

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

这没有意义,因为如果child为null,显然ContainerFromItem(null)将返回null,使child为null。

【讨论】:

以上是关于如何在 wpf 中的 treeviewitem 中访问 treeviewitem?的主要内容,如果未能解决你的问题,请参考以下文章

wpf treeview中动态创建的treeViewItem如何用右键触发菜单?

双击访问C#中的WPF TreeViewItem

如何从 WPF 树视图中删除边框

禁用WPF TreeView(或TreeViewItem)选择?

C# WPF TreeViewItem MouseDoubleClick 事件在 TreeViewItem 与 TreeViewItem.Header

在wpf中将treeviewitem显示为网格行