WPF Treeview控件开虚拟化后定位节点

 不开虚拟化,可以用下面的方法直接定位

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TreeView Name="myTreeView">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding Name}" />
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            
            // 示例数据
            var root = new TreeNode { Name = "Root" };
            for (int i = 0; i < 1000; i++)
            {
                var child = new TreeNode { Name = "Child " + i };
                for (int j = 0; j < 10; j++)
                {
                    child.Children.Add(new TreeNode { Name = "SubChild " + j });
                }
                root.Children.Add(child);
            }

            myTreeView.ItemsSource = new ObservableCollection<TreeNode> { root };

            // 等待数据绑定完成后选中并定位到指定节点
            this.Loaded += (s, e) => {
                var nodeToSelect = root.Children[51].Children[5]; // 举例:选中第51个Child的第6个SubChild
                SelectAndScrollToNode(myTreeView, nodeToSelect);
            };
        }

        private void SelectAndScrollToNode(TreeView treeView, TreeNode targetNode)
        {
            // 展开到目标节点
            ExpandAndSelect(treeView, targetNode);
        }

   

        public static IEnumerable<T> FindLogicalChildren<T>(DependencyObject obj) where T : DependencyObject
        {
            if (obj != null)
            {
                if (obj is T)
                    yield return obj as T;
                foreach (DependencyObject child in LogicalTreeHelper.GetChildren(obj).OfType<DependencyObject>())
                    foreach (T c in FindLogicalChildren<T>(child))
                        yield return c;
            }
        }



        private void ExpandAndSelect(TreeView treeView, TreeNode targetNode)
        {
            foreach (var node in (ObservableCollection<TreeNode>)treeView.ItemsSource)
            {
                if (ExpandAndSelectInternal(treeView, node, targetNode))
                    break;
            }
        }

        private bool ExpandAndSelectInternal(ItemsControl parent, TreeNode currentNode, TreeNode targetNode)
        {
            if (currentNode == targetNode)
            {
                if (parent.ItemContainerGenerator.ContainerFromItem(currentNode) is TreeViewItem )
                {
                    var currentItem = parent.ItemContainerGenerator.ContainerFromItem(currentNode) as TreeViewItem;
                    currentItem.IsSelected = true;
                    currentItem.BringIntoView();
                    return true;
                }
            }

            if (parent.ItemContainerGenerator.ContainerFromItem(currentNode) is TreeViewItem)
            {
                var item = parent.ItemContainerGenerator.ContainerFromItem(currentNode) as TreeViewItem;
                item.IsExpanded = true;
                item.UpdateLayout();
                
                foreach (var childNode in currentNode.Children)
                {
                    if (ExpandAndSelectInternal(item, childNode, targetNode))
                    {
                        item.IsExpanded = true;
                        item.UpdateLayout();
                        if (item.ItemContainerGenerator.ContainerFromItem(targetNode) is TreeViewItem )
                        {
                            var targetItem = item.ItemContainerGenerator.ContainerFromItem(targetNode) as TreeViewItem;
                            targetItem.IsSelected = true;
                            targetItem.BringIntoView();
                        }
                        return true;
                    }
                }
            }

            return false;
        }
    }

 
    public class TreeNode
    {
        public TreeNode()
        {
            Children = new ObservableCollection<TreeNode>();
        }
        public string Name { get; set; }
        public ObservableCollection<TreeNode> Children { get; set; }
    }

但是如果开了虚拟化,需要默认显示的节点很可能不在可视化树上,所以这套方法就不能用了。

解决办法:计算默认选中项的垂直位置,直接操作滚动条移动到目标节点。

 private void SelectAndScrollToNode(TreeView treeView, TreeNode targetNode)
        {
            // 展开到目标节点
            ExpandAndSelect(treeView, targetNode);
            //根据targetNode计算滚动条的位置,这里就直接取中间位置了
            TreeViewAutomationPeer lvap = new TreeViewAutomationPeer(treeView);
            var svap = lvap.GetPattern(PatternInterface.Scroll) as ScrollViewerAutomationPeer;
            var scroll = svap.Owner as ScrollViewer;
            double hight = scroll.ScrollableHeight;
            scroll.ScrollToVerticalOffset(hight / 2);
        }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/683112.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电脑在线怎么改图片格式?3步改图片格式的操作步骤

在日常生活和工作中经常会因为不同的用途&#xff0c;需要使用不同格式的图片&#xff0c;那么如果遇到图片格式问题时&#xff0c;有什么方法能够快速在线转图片格式呢&#xff1f; 想要快速将图片格式转换成自己需要使用的格式&#xff0c;比较简单的一种方法可以使用网上的…

使用 Django 和 MQTT 构建实时数据传输应用

文章目录 什么是 MQTT&#xff1f;Django 中的 MQTT结论 在现代的 Web 应用程序开发中&#xff0c;实时数据传输变得越来越重要。MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的发布/订阅消息传输协议&#xff0c;而 Django 是一个流行的 Pyt…

66、API攻防——接口安全阿里云KEYPostmanDVWS

文章目录 一、工具使用——Postman自动化测试二、安全问题——Dvws泄露&鉴权&XXE三、安全问题——阿里KEY信息泄露利用 dvws-node 一、工具使用——Postman自动化测试 二、安全问题——Dvws泄露&鉴权&XXE 路径中出现/api/&#xff0c;一般都是接口。 请求包是…

Jail管理器AppJail的使用@FreeBSD

Jail的简介 Jail是FreeBSD操作系统中一个功能强大的安全机制&#xff0c;自FreeBSD 4.X版本起便投入使用&#xff0c;并且随着系统的发展&#xff0c;其功能、效率、稳定性和安全性得到了持续的强化。 Jail基于chroot的概念&#xff0c;通过更改一系列程序的根目录&#xff0…

【面试题】创建两个线程交替打印100以内数字(一个打印偶数一个打印奇数)

阅读导航 一、问题概述二、解决思路三、代码实现四、代码优化 一、问题概述 面试官&#xff1a;C多线程了解吗&#xff1f;你给我写一下&#xff0c;起两个线程交替打印0~100的奇偶数。就是有两个线程&#xff0c;一个线程打印奇数另一个打印偶数&#xff0c;它们交替输出&…

rust学习(字节数组转string)

最新在写数据传输相关的操作&#xff0c;发现string一个有趣的现象&#xff0c;代码如下&#xff1a; fn main() {let mut data:[u8;32] [0;32];data[0] a as u8;let my_str1 String::from_utf8_lossy(&data);let my_str my_str1.trim();println!("my_str len is…

用框架思维学Java:集合概览

集合这个词&#xff0c;耳熟能详&#xff0c;从小学一年级开始&#xff0c;每天早上做操时都会听到这两个字&#xff1a; 高中数学又学习到了新的集合&#xff1a; 那么Java中的集合是什么呢&#xff1f; 一&#xff0c;前言 1&#xff0c;什么是Java集合 数学集合是Java集…

模式识别涉及的常用算法

一、线性回归 1.算法执行流程&#xff1a; 算法的执行流程可以简述如下&#xff1a; 导入必要的库&#xff1a; 导入NumPy库&#xff0c;用于数值计算。导入Matplotlib库&#xff0c;用于数据可视化。导入Pandas库&#xff0c;用于数据处理&#xff08;尽管在这个例子中&#…

【Git】Git 的初识和安装

一、提出问题 不知道你工作或学习时&#xff0c;有没有遇到这样的情况&#xff1a;在编写各种文档时&#xff0c;为了防止文档丢失&#xff0c;更改失误&#xff0c;失误后能恢复到原来的版本&#xff0c;不得不复制出⼀个副本&#xff0c;比如&#xff1a; 设计文档v1设计文…

Python字符串操作详解(超详细)

Python字符串操作详解 目录 Python字符串操作详解一. 字符串创建二. 字符串拼接1. 使用 运算符2. 使用 .join() 方法 三. 字符串索引和切片1. 字符串索引2. 字符串切片3. 字符串长度和负索引4. 字符串不可变性 四. 字符串长度五. 字符串转换六. 查找子字符串七. 字符串替换八.…

xml创建模型组合体

XML创建模型组合体 创建步骤模型准备模型处理模型文件XML编写 效果 创建步骤 模型准备 CAD 提供的原始模型如下&#xff1a; 该模型存在的问题&#xff1a; 单位问题&#xff1a;CAD出图的是 mm 为单位&#xff0c;但是 mujoco 建模这边用的是以 m 为单位的&#xff1b;原点…

二刷算法训练营Day22 | 二叉树(8/9)

目录 详细布置&#xff1a; 1. 235. 二叉搜索树的最近公共祖先 2. 701. 二叉搜索树中的插入操作 3. 450. 删除二叉搜索树中的节点 详细布置&#xff1a; 1. 235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共…

onenet踩坑连接mqtt

一定注意这个version为默认 完整说明https://open.iot.10086.cn/doc/v5/fuse/detail/922 注意这里的的device是名称&#xff0c;不是id,最好产品开发那里就是都是一个名字

华安保险:核心系统分布式升级,提升保费规模处理能力2-3倍 | OceanBase企业案例

在3月20日的2024 OceanBase数据库城市行的活动中&#xff0c;安保险信息科技部总经理王在平发表了以“保险行业核心业务系统分布式架构实践”为主题的演讲。本文为该演讲的精彩回顾。 早在2019年&#xff0c;华安保险便开始与OceanBase接触&#xff0c;并着手进行数据库的升级…

spring boot3登录开发-2(3邮件验证码接口实现)

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 目录 写在前面 上文衔接 接口设计与实现 1.接口分析 2.实现思路 3.代码实现 1.定义验证码短信HTML模板枚举类 2.定义验证码业务接口 3. 验证码业务接口实现 4.控制层代码 4.测试 写…

三、Mapper XML的解析和注册使用

流程&#xff1a; 1.Resources加载MyBatis配置文件生成Reader字符流 2.SqlSessionFactoryBuilder开始引导构建SqlSessionFactory&#xff0c;包括两步&#xff1a; 第一步是在XMLConfigBuilder中使用dom4j解析xml文件&#xff0c;将解析的SQL包装成MappedStatement对象存入Con…

微信小程序-案例:本地生活-首页(不使用网络数据请求)

一、 1.页面效果&#xff1a; 二、 1.新建项目并添加页面 在app.json文件中&#xff1a; "pages": ["pages/home/home","pages/message/message","pages/contact/contact"] 2.配置导航栏效果 在app.json文件中&#xff1a; &quo…

Windows11系统 和Android 调试桥(Android Debug Bridge,ADB)工具安装,app抓取日志内容

文章目录 目录 文章目录 安装流程 小结 概要安装流程技术细节小结 概要 Android调试桥&#xff08;ADB&#xff09;是一种多功能命令行工具&#xff0c;它允许开发者与连接到计算机上的Android设备进行通信和控制。ADB工具的作用包括但不限于&#xff1a; 安装和卸载应用程序&…

Three.js中的Raycasting技术:实现3D场景交互事件的Raycaster详解

前言 在Web开发中&#xff0c;Three.js是一个极为强大的库&#xff0c;它让开发者能够轻松地在浏览器中创建和展示3D图形。随着3D技术在网页设计、游戏开发、数据可视化等领域的广泛应用&#xff0c;用户与3D场景的交互变得日益重要。而要实现这种交互&#xff0c;一个核心的技…

初识C++ · 反向迭代器简介

目录 前言 反向迭代器的实现 前言 继模拟实现了list和vector之后&#xff0c;我们对迭代器的印象也是加深了许多&#xff0c;但是我们实现的都是正向迭代器&#xff0c;还没有实现反向迭代器&#xff0c;那么为什么迟迟不实现呢&#xff1f;因为难吗&#xff1f;实际上还好。…