本文介绍了获取TreeView逻辑元素的TreeViewItem的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的树状视图看起来像这样

My tree view seems like this

<TreeView x:Name="ArticlesTreeView" Grid.Column="0" AllowDrop="True">
            <TreeView.Resources>
                <HierarchicalDataTemplate   DataType="{x:Type structure:NewsPaperDocument}" ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding Name}" Tag="{Binding Object}" FontWeight="Bold" />
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type structure:NewsPaperPage}" ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding Name}" Tag="{Binding Object}" Foreground="#00a300" />
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type structure:NewsPaperTitle}" ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding Name}" Tag="{Binding Object}" Foreground="#da532c" />
                </HierarchicalDataTemplate>
                <DataTemplate DataType="{x:Type structure:NewsPaperBlock}">
                    <TextBlock Text="{Binding Name}" Tag="{Binding Object}" Foreground="#2b5797" />
                </DataTemplate>
            </TreeView.Resources>
        </TreeView>

ArticlesTreeView.SelectedItem中存储类NewsPaperDocument, NewsPaperPage, etc的实例.如何获得与SelectedItem关联的TreeViewItem?我尝试使用VisualTreeHelper.GetParent(elem);,但是SelectedItem没有类型DependencyObject

In ArticlesTreeView.SelectedItem stores instance of classes NewsPaperDocument, NewsPaperPage, etc. How can I get TreeViewItem associated with SelectedItem? I try to use VisualTreeHelper.GetParent(elem);, but SelectedItem doesn't has type DependencyObject

UPD1 添加简单的示例,以演示问题. ArticlesTreeView_SelectedItemChanged中的item始终null

UPD1 Add simple sample, that demonstrate problem. item in ArticlesTreeView_SelectedItemChanged always null

XAML

<Window x:Class="TestTree.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:testTree="clr-namespace:TestTree"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TreeView x:Name="ArticlesTreeView" Grid.Column="0" AllowDrop="True" SelectedItemChanged="ArticlesTreeView_SelectedItemChanged">
        <TreeView.Resources>
            <HierarchicalDataTemplate   DataType="{x:Type testTree:A}" ItemsSource="{Binding Children}">
                <TextBlock Text="{Binding Name}" FontWeight="Bold" />
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type testTree:B}" ItemsSource="{Binding Children}">
                <TextBlock Text="{Binding Name}" Foreground="#00a300" />
            </HierarchicalDataTemplate>
            <DataTemplate DataType="{x:Type testTree:C}">
                <TextBlock Text="{Binding Name}" Foreground="#2b5797" />
            </DataTemplate>
        </TreeView.Resources>
    </TreeView>
</Grid>

CS

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace TestTree
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var a = new A
            {
                Name = "a",
                Children = new List<B>
                {
                    new B
                    {
                        Name = "b1",
                        Children = new List<C>
                        {
                            new C{Name = "c1"},
                            new C{Name = "c2"},
                            new C{Name = "c3"}
                        },
                    },
                    new B
                    {
                        Name = "b2",
                        Children = new List<C>
                        {
                            new C{Name = "c1"},
                            new C{Name = "c2"},
                            new C{Name = "c3"}
                        },
                    },
                    new B
                    {
                        Name = "b3",
                        Children = new List<C>
                        {
                            new C{Name = "c1"},
                            new C{Name = "c2"},
                            new C{Name = "c3"}
                        },
                    }
                }
            };
            ArticlesTreeView.ItemsSource = new List<A> { a };
        }

        private void ArticlesTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            ItemContainerGenerator gen = ArticlesTreeView.ItemContainerGenerator;
            var item = gen.ContainerFromItem(ArticlesTreeView.SelectedItem);
        }
    }

    internal class A
    {
        public string Name { set; get; }

        public List<B> Children { set; get; }
    }

    internal class B
    {
        public string Name { set; get; }

        public List<C> Children { set; get; }
    }

    internal class C
    {
        public string Name { set; get; }
    }
}

推荐答案

如果我正确理解了您的意思,您想从SelectedItem

if I got you correctly you want to retrieve the TreeViewItem from the SelectedItem

因此您可以使用ItemContainerGenerator

        ItemContainerGenerator gen = ArticlesTreeView.ItemContainerGenerator;
        TreeViewItem item = gen.ContainerFromItem(ArticlesTreeView.SelectedItem) as TreeViewItem;

从嵌套项目中获取TreeViewItem

由于每个TreeViewItem都有其自己的ItemContainerGenerator的原因,因此为了从嵌套项目中找到容器,我们需要递归树的深度

due to the reason that every TreeViewItem has it's own ItemContainerGenerator so in order to find the container from the nested items we need to recurse the depth of the tree

    private void ArticlesTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        var item = ContainerFromItem(ArticlesTreeView.ItemContainerGenerator, ArticlesTreeView.SelectedItem);
    }

    private static TreeViewItem ContainerFromItem(ItemContainerGenerator containerGenerator, object item)
    {
        TreeViewItem container = (TreeViewItem)containerGenerator.ContainerFromItem(item);
        if (container != null)
            return container;

        foreach (object childItem in containerGenerator.Items)
        {
            TreeViewItem parent = containerGenerator.ContainerFromItem(childItem) as TreeViewItem;
            if (parent == null)
                continue;

            container = parent.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
            if (container != null)
                return container;

            container = ContainerFromItem(parent.ItemContainerGenerator, item);
            if (container != null)
                return container;
        }
        return null;
    }

这篇关于获取TreeView逻辑元素的TreeViewItem的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 23:48