WPF TreeView 虚拟化-设置滚动到选中项
前言
列表滚动到具体的数据项?
ListBox提供了简易快捷的滚动定位函数ScrollIntoView。
TreeView树状结构列表,则没有此类方法,无法与ListBox一样,直接设置滚动到具体的数据项。
同时,SelectedItem也是只读的,无法设置SelectedItem来间接的设置滚动项。
TreeView滚动定位
1. 对TreeViewItem添加一个附加属性IsScrolledToViewWhenSelected,在属性变更事件中,添加对Loaded事件的订阅和注销
static void OnIsScrolledToViewWhenSelectedChanged(
DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
if (depObj is TreeViewItem treeViewItem && e.NewValue is bool isIntoViewWhenSelected)
{
treeViewItem.Loaded -= TreeViewItem_Loaded;
if (isIntoViewWhenSelected)
{
treeViewItem.Loaded += TreeViewItem_Loaded;
}
}
}
2. 在Loaded事件中,根据当前TreeViewItem是否选中,调用是否滚动到视图区域的逻辑
static void TreeViewItem_Loaded(object sender, RoutedEventArgs e)
{
var treeViewItem = e.OriginalSource as TreeViewItem;
if (treeViewItem != null)
{
treeViewItem.Loaded -= TreeViewItem_Loaded;
if (treeViewItem.IsSelected)
{
treeViewItem.BringIntoView();
}
}
}
此处,对TreeView添加附加属性处理,也是可以的
虚拟化后的TreeView滚动定位
因开启了虚拟化,界面上不在当前视觉内的数据项,没有生成相应的视觉树,即无法找到TreeViewItem。
所以虚拟化后,使用TreeViewItem添加附加属性,而不是TreeView。因为TreeView无法对视觉树外的项,查找并定位;而TreeViewItem...emmm~可以使用黑科技处理,详情如下
1. 在上面逻辑的基础上,添加对虚拟化的处理。
此处添加了对虚拟化的判断,虚拟化时如果已经完成了滚动定位,则对后续的逻辑直接跳过,避免选中项的定位被干扰。
static void OnIsScrolledToViewWhenSelectedChanged(
DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
if (depObj is TreeViewItem treeViewItem && e.NewValue is bool isIntoViewWhenSelected)
{
treeViewItem.Loaded -= TreeViewItem_Loaded;
//获取父控件TreeView
var treeView = treeViewItem.FindVisualParent<TreeView>();
if (isIntoViewWhenSelected)
{
//开启了虚拟化且未完成滚动,直接返回
var isOpeningVitualizing = ScrollViewer.GetCanContentScroll(treeView) && VirtualizingPanel.GetIsVirtualizing(treeView);
if (isOpeningVitualizing && GetHasSetSelectedItemVisible(treeView))
{
return;
}
treeViewItem.Loaded += TreeViewItem_Loaded;
}
}
}
2. 在之前逻辑的基础上,添加虚拟化的判断
如果开启了虚拟化,
- 列表项未选中时,设置滚动到视图中
- 列表项选中时,设置已完成,并滚动到视图中
黑科技:
列表数据加载时,每项都滚动到视图中。
而虚拟化列表实际上初始化的项个数,在默认设置下,比可视化区域的项个数要多很一部分。
所以在单个数据加载时,设置滚动视图,会带动更多原本不在视图内的数据项,生成视觉树。
static void TreeViewItem_Loaded(object sender, RoutedEventArgs e)
{
var treeViewItem = e.OriginalSource as TreeViewItem;
if (treeViewItem != null)
{
treeViewItem.Loaded -= TreeViewItem_Loaded;
//获取父控件TreeView
var treeView = treeViewItem.FindVisualParent<TreeView>();
//是否开启了虚拟化
var isOpeningVirtualizing = ScrollViewer.GetCanContentScroll(treeView) && VirtualizingPanel.GetIsVirtualizing(treeView);
if (isOpeningVirtualizing)
{
if (treeViewItem.IsSelected)
{
//设置已完成滚动,减少剩余项的加载判断
SetHasSetSelectedItemVisible(treeView, true);
treeViewItem.BringIntoView();
}
else
{
treeViewItem.BringIntoView();
}
}
else if(treeViewItem.IsSelected)
{
treeViewItem.BringIntoView();
}
}
}
关键字:TreeView虚拟化、滚动到选中项
WPF TreeView 虚拟化-设置滚动到选中项的更多相关文章
- 自定义Behavior 实现Listbox自动滚动到选中项
原文:自定义Behavior 实现Listbox自动滚动到选中项 blend为我们提供方便的behavior来扩展我们的控件,写好之后就可以在blend中方便的使用了. 下面是自定义的behavior ...
- angularjs中设置select的选中项
最近用angularjs比较多,里面有很多自己的方法,都不咋会用,这篇只是个笔记,防止自己忘记 <select style="width:100%" ng-model=&qu ...
- jquery动态生成的select下拉框,怎么设置默认的选中项?
这两天都被这问题困扰,可能是我不太懂前端.我做layui表格行编辑,点击编辑按钮弹出layer,里边有一个民族的下拉框不能直接显示后台传过来的值.我把民族数组用jquery添加到了select里边,可 ...
- ASP.NET--ListBox初始化时设置多个选中项
public void SetSelectedListItem(ListBox lst, List<DBServerIPBind> source) { ; i < source.Co ...
- jquery 设置asp:dropdownlist 选中项
$("#ddlPro").find('option').each(function () { this.selected = (this.text == dlprom); });
- 根据值设置select的选中项
$('.selector').attr("checked", true); <s:iterator value="jobSelect" id=" ...
- Winform下的Combox根据值来选中项
其实很简单,因为Combox的Item是一个K/V的object,那么就可以把它的items转换成IEnumerable<DictionaryEntry>类型的(System.Collec ...
- layui动态修改select的选中项
layui动态修改select的选中项:(在layUI下给select设置默认选项) 例: $("select[name='result']").val(11); //重新渲染表单 ...
- WPF 列表虚拟化时的滚动方式
ListBox的滚动方式 分为像素滚动和列表项滚动 通过ListBox的附加属性ScrollViewer.CanContentScroll来设置.因此ListBox的默认模板中,含有ScrollVie ...
随机推荐
- 1.1 Spring 概述
1.1 Spring 概述 1.1.1 Spring 的简史 第一阶段:xml配置 Spring 1.x时代使用xml配置Bean 第二阶段:注解配置 Spring2.x Spring 提供了声明B ...
- laravel起步的一些小问题
工作中主要使用的是.NET,PHP只是我业余喜欢的一门语言,而之前一直用的是yii2框架,觉得Yii2是最好的框架了,然而,laravel在业界的名声太大,被誉为:最优雅的框架,所以,我决定花点时间研 ...
- Rancher 2.3实现K8S一键式升级!再也不用同步升级Rancher啦!
在Rancher 2.3之前,Rancher的新版本总是随着Kubernetes的新版本一起发布,如果你想要使用最新版本的Kubernetes,那么你需要先升级Rancher才能使用.Rancher ...
- springboot搭建项目,实现Java生成随机图片验证码。
这篇文章主要介绍了如何通过Java如何生成验证码并验证.验证码的作用我想必大家都知道,话不多说开始实施! 首先创建一个springboot项目以下是项目结构,内有utli工具类.存放生成图片验证码方法 ...
- Redis学习二(数据操作).
key 操作 删除 key:del key 批量删除key:redis-cli -a(密码)keys "QXJ_*"| xargs redis-cli -a(密码)del 查看所有 ...
- IT兄弟连 HTML5教程 DIV+CSS网页标准化布局 小结及习题
小结 DIV+CSS布局页面的优势:表现和内容相分离.代码简洁,提高页面浏览速度.易于维护和改版.提高搜索引擎对网页的索引效率.每个HTML元素都可以看作一个区块,类似于装了东西的盒子,称为盒子模式. ...
- Redis入门(四)-Java操作Redis
<Redis入门>系列文章的第四篇,这一节看一下如何用Java版本的redis客户端工具--Jedis来操作redis. Jedis封装了丰富的api来对redis的五种数据类型 stri ...
- WPF之实现控件内容拖动
以下分别记录label.listbox.treeview三个控件的拖动示例: 1.对被拖动控件,实现拖动事件,主要是通过各种鼠标事件,实现DragDrop.DoDragDrop方法. 2.对于需要拖动 ...
- 剑指offer笔记面试题6----从未到头打印链表
题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值.链表节点定义如下: struct ListNode{ int m_nKey; ListNode* m_pNext; } 测试用例: 功能测 ...
- Android PopupWindow增加半透明蒙层
先看效果图: BasePopupWindowWithMask.class package com.example.popupwindowwithmask; import android.content ...