获取 TreeView 逻辑元素的 TreeViewItem

2023-12-10

我的树视图看起来像这样

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

In ArticlesTreeView.SelectedItem存储类的实例NewsPaperDocument, NewsPaperPage, etc。我怎样才能得到TreeViewItem有关联SelectedItem?我尝试使用VisualTreeHelper.GetParent(elem);, but SelectedItem没有类型DependencyObject

UPD1添加简单的示例来演示问题。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; }
    }
}

如果我没猜错的话你想取回TreeViewItem来自SelectedItem

所以你可以利用ItemContainerGenerator

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

从嵌套项目中获取 TreeViewItem

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

    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;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取 TreeView 逻辑元素的 TreeViewItem 的相关文章

  • VB.NET 相当于 C# 属性简写吗?

    是否有与 C 等效的 VB NET public string FirstName get set 我知道你能做到 Public Property name As String Get Return name ToString End Ge
  • 如何检查QProcess是否正确执行?

    QProcess process sdcompare QString command sdcompare QStringList args sdcompare command sdcompare diff args sdcompare lt
  • 如何让窗口最大化时所有控件按比例调整大小?

    当我单击最大化按钮时 窗口最大化 但控件未按比例调整大小 使控件相应调整大小的最佳方法是什么 我正在使用MVVM 这是我的代码
  • 向 Nhibernate 发出 SQL 查询

    如何将此 SQL 查询发送给 Nhibernate SELECT Customer name FROM Company INNER JOIN Customer ON Company CompanyId Customer CompanyId
  • 在新的浏览器进程中打开 URL

    我需要在新的浏览器进程中打开 URL 当浏览器进程退出时我需要收到通知 我当前使用的代码如下 Process browser new Process browser EnableRaisingEvents true browser Star
  • 在 Unity 进程和另一个 C# 进程之间进行本地 IPC 的最快方法 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我希望每秒大约 30 次从 C 应用程序向我的 Unity 应用程序传送大量数据 由于 Unity 不支持映射内存和管道 我考虑了 t
  • C++中的类查找结构体数组

    我正在尝试创建一个结构数组 它将输入字符串链接到类 如下所示 struct string command CommandPath cPath cPathLookup set an alarm AlarmCommandPath send an
  • 存储来自其他程序的事件

    我想将其他应用程序的事件存储在我自己的应用程序中 事件示例 打开 最小化 Word 或打开文件时 这样的事可能吗 运行程序 http msdn microsoft com en us library ms813609 aspx and 打开
  • 在 C# 中循环遍历文件文件夹的最简单方法是什么?

    我尝试编写一个程序 使用包含相关文件路径的配置文件来导航本地文件系统 我的问题是 在 C 中执行文件 I O 这将是从桌面应用程序到服务器并返回 和文件系统导航时使用的最佳实践是什么 我知道如何谷歌 并且找到了几种解决方案 但我想知道各种功
  • C# Dns.GetHostEntry 不返回连接到 WiFi 的移动设备的名称

    我有一个 C 中的 Windows 窗体应用程序 我试图获取列表中所有客户端的主机名 下面给出的是 ra00l 来自此链接的代码示例 GetHostEntry 非常慢 https stackoverflow com questions 99
  • 使用 JNI 从 Java 代码中检索 String 值的内存泄漏

    我使用 GetStringUTFChars 从使用 JNI 的 java 代码中检索字符串的值 并使用 ReleaseStringUTFChars 释放该字符串 当代码在 JRE 1 4 上运行时 不会出现内存泄漏 但如果相同的代码在 JR
  • Rx 中是否有与 Task.ContinueWith 运算符等效的操作?

    Rx 中是否有与 Task ContinueWith 运算符等效的操作 我正在将 Rx 与 Silverlight 一起使用 我正在使用 FromAsyncPattern 方法进行两个 Web 服务调用 并且我想这样做同步地 var o1
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • Visual Studio 中的测试单独成功,但一组失败

    当我在 Visual Studio 中单独运行测试时 它们都顺利通过 然而 当我同时运行所有这些时 有些通过 有些失败 我尝试在每个测试方法之间暂停 1 秒 但没有成功 有任何想法吗 在此先感谢您的帮助 你们可能有一些共享数据 检查正在使用
  • 用于 C# 的 TripleDES IV?

    所以当我说这样的话 TripleDES tripledes TripleDES Create Rfc2898DeriveBytes pdb new Rfc2898DeriveBytes password plain tripledes Ke
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • 如何在 C# 中调整图像大小同时保持高质量?

    我从这里找到了一篇关于图像处理的文章 http www switchonthecode com tutorials csharp tutorial image editing saving cropping and resizing htt
  • 在wpf中移动鼠标

    我目前正在寻找一种在 wpf 中移动鼠标的方法 我发现的只是我无法可靠实现的非托管方法调用 有没有一种简单的方法可以将鼠标光标移动到某个地方 即 双击后 我肯定在这里遗漏了一些东西 添加对System Windows Forms dll的引
  • memset 未填充数组

    u32 iterations 5 u32 ecx u32 malloc sizeof u32 iterations memset ecx 0xBAADF00D sizeof u32 iterations printf 8X n ecx 0
  • 如何使用 Word Automation 获取页面范围

    如何使用办公自动化找到 Microsoft Word 中第 n 页的范围 似乎没有 getPageRange n 函数 并且不清楚它们是如何划分的 这就是您从 VBA 执行此操作的方法 转换为 Matlab COM 调用应该相当简单 Pub

随机推荐