VisualTreeHelper使用——使用BFS实现高效率的视觉对象搜索
BFS,即广度优先搜索,是一种典型的图论算法。BFS算法与DFS(深度优先搜索)算法相对应,都是寻找图论中寻路的常用算法,两者的实现各有优点。
其中DFS算法常用递归实现,也就是常见的一条路找到黑再找另一条。如果我们要找的数据存储在一棵树最靠左侧的一边时,DFS的好处就显现出来了。无论数据在树的多深,DFS都能在线性的时间内找出这个数据。
而BFS算法常用队列实现,在查找树内对象时,会由树的根节点,一层一层向下找到目标。BFS的好处在于不管数据存在树的哪个节点,BFS都能以一个比较恒定的速度找到对象,这个速度几乎只与没寻找的深度和每层的节点数量相关。
所以在遍历视觉树时使用BFS相较于DFS有什么好处呢?
一个很明显的视觉树遍历特点就是,一般要找到的视觉对象都不会存储在离根节点特别远的地方。此时BFS相比DFS更不容易出现一条分支摸到黑啥都没找的情况。
话不多少了,上代码!
public static class VisualTreeExtension
{ /// <summary>
/// Find all children T in dpObj using BFS.
/// </summary>
/// <param name="maxDepth">max finding depth of visual tree.</param>
/// <param name="maxChildCount">maximum number of child nodes. Whose number of child nodes exceeds this value will be excluded</param>
/// <returns></returns>
public static IEnumerable<T> GetChild<T>(this DependencyObject dependencyObject, uint maxDepth = uint.MaxValue, uint maxChildCount = )
where T : DependencyObject
{
int depth = ;
int count = VisualTreeHelper.GetChildrenCount(dependencyObject);
Queue<DependencyObject> qObjs = new Queue<DependencyObject>();
for (int i = ; i < count; i++)
{
qObjs.Enqueue(VisualTreeHelper.GetChild(dependencyObject, i));
} while (qObjs.Count != )
{
if (depth > maxDepth)
yield break;
depth++;
count = qObjs.Count;
for (int i = ; i < count; i++)
{
var obj = qObjs.Dequeue();
if (obj is T result)
yield return result;
int child_count = VisualTreeHelper.GetChildrenCount(obj);
if (child_count > maxChildCount)
continue;
for (int j = ; j < child_count; j++)
{
qObjs.Enqueue(VisualTreeHelper.GetChild(obj, j));
}
}
}
} /// <summary>
/// Find all children T in dpObj using BFS.
/// </summary>
/// <param name="maxDepth">max finding depth of visual tree.</param>
/// <param name="maxChildCount">maximum number of child nodes. Whose number of child nodes exceeds this value will be excluded</param>
/// <returns></returns>
public static IEnumerable<T> GetChild<T>(this DependencyObject dependencyObject, string name, uint maxDepth = uint.MaxValue, uint maxChildCount = )
where T : FrameworkElement
{
int depth = ;
int count = VisualTreeHelper.GetChildrenCount(dependencyObject);
Queue<DependencyObject> qObjs = new Queue<DependencyObject>(count);
for (int i = ; i < count; i++)
{
qObjs.Enqueue(VisualTreeHelper.GetChild(dependencyObject, i));
} while (qObjs.Count != )
{
if (depth > maxDepth)
yield break;
depth++;
count = qObjs.Count;
for (int i = ; i < count; i++)
{
var obj = qObjs.Dequeue();
if (obj is T result && result.Name == name)
yield return result;
int child_count = VisualTreeHelper.GetChildrenCount(obj);
if (child_count > maxChildCount)
continue;
for (int j = ; j < child_count; j++)
{
qObjs.Enqueue(VisualTreeHelper.GetChild(obj, j));
}
}
}
}
}
使用方法:
var scrollViewer = listView.GetChild<ScrollViewer>().First();
也可以手动指定BFS的最大深度和最大子节点数量,避免遍历浪费太多时间
VisualTreeHelper使用——使用BFS实现高效率的视觉对象搜索的更多相关文章
- Power BI 可视化交互/视觉对象交互
xx Power BI的官方文档特别好,但是具体到自己使用的时候,有些知识点,可能看完文档忘了,导致有些功能做不出来...网络上资料还比较匮乏... 自己没事还是多总结下吧... 比如: 文档上写的很 ...
- 搜索分析(DFS、BFS、递归、记忆化搜索)
搜索分析(DFS.BFS.递归.记忆化搜索) 1.线性查找 在数组a[]={0,1,2,3,4,5,6,7,8,9,10}中查找1这个元素. (1)普通搜索方法,一个循环从0到10搜索,这里略. (2 ...
- poj1753 bfs+奇偶性减枝//状压搜索
http://poj.org/problem?id=1753 题意:有个4*4的棋盘,上面摆着黑棋和白旗,b代表黑棋,w代表白棋,现在有一种操作,如果你想要改变某一个棋子的颜色,那么它周围(前后左右) ...
- hdu1428漫步校园( 最短路+BFS(优先队列)+记忆化搜索(DFS))
Problem Description LL最近沉迷于AC不能自拔,每天寝室.机房两点一线.由于长时间坐在电脑边,缺乏运动.他决定充分利用每次从寝室到机房的时间,在校园里散散步.整个HDU校园呈方形布 ...
- 用BFS和DFS解决圆盘状态搜索问题
人工智能课程的实验(我的解法其实更像是算法课程的实验) 用到的算法:深度优先搜索.宽度优先搜索(状态扩展的不同策略) 数据结构:表示状态的结构体.多维数组 (可能是最近做算法竞赛题的影响,这次并不像以 ...
- BFS(一):广度优先搜索的基本思想
广度优先搜索BFS(Breadth First Search)也称为宽度优先搜索,它是一种先生成的结点先扩展的策略. 在广度优先搜索算法中,解答树上结点的扩展是按它们在树中的层次进行的.首先生成第一层 ...
- 《纵向切入ASP.NET 3.5控件和组件开发技术》笔记:高效率事件集合对象
在之前讲的几个例子中,使用的是最普通的定义事件方法,比如KingTextBox中事件是这样定义的:/// <summary>/// 获得本书更多内容,请看:/// http://blog. ...
- AOJ 0121: Seven Puzzle【BFS】
From: AOJ 0121 思路:与前几题的bfs不同,这次的bfs没有明确的移动对象,看似任意一个数都可以当成对象移动.这时我们只需要抓住一个格子就行,比如我们把0作为移动对象,那么0在地图中漫游 ...
- 数据结构之DFS与BFS实现
本文主要包括以下内容 邻接矩阵实现无向图的BFS与DFS 邻接表实现无向图的BFS与DFS 理论介绍 深度优先搜索介绍 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似 ...
随机推荐
- windows API 第 11 篇 GetCurrentDirectory SetCurrentDirectory
GetCurrentDirectory函数获得当前文件所在的目录,并不是进程的目录(debug 和 release),它和GetCommandLine不同这里只讲 GetCurrentDirector ...
- Gym-102141E
https://vjudge.net/problem/Gym-102141E 用set乱搞 #include<iostream> #include<cstdio> #inclu ...
- get请求中文乱码
get请求时要将url进行encodeURI http://www.ruanyifeng.com/blog/2010/02/url_encoding.html http://www.ruanyifen ...
- 如何设置td中溢出内容的隐藏显示
<style type="text/css"> table { table-layout:fixed; } td { overflow:hidden; word-bre ...
- Spring注解驱动开发(三)-----自动装配
自动装配 概念 Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值. @Autowired-----自动注入 1.默认优先按照类型去容器中找对应的组件 application ...
- 禁用 ipv6
# 禁用整个系统所有接口的IPv6 net.ipv6.conf.all.disable_ipv6 = # 禁用某一个指定接口的IPv6(例如:eth0, lo) net.ipv6.conf.lo.di ...
- chgrp权限命令
功能说明:变更文件或目录的所属群组. 语 法:chgrp [-cfhRv][--help][--version][所属群组][文件或目录...] 或 chgrp [-cfhRv][--help][-- ...
- TZOJ 4021 Ugly Problem(线段树区间子段最大)
描述 给定一个序列A[0],A[1],…A[N-1],要求找到p0,p1,p2,p3使得A[p0]+A[p0+1]+…+A[p1] + A[p2]+A[p2+1]+…+A[p3]最大(0<=p0 ...
- Nonsense Time
Nonsense Time 时间限制: 10 Sec 内存限制: 128 MB 题目描述 You a given a permutation p1,p2,…,pn of size n. Initia ...
- Java数据结构和算法(七)--AVL树
在上篇博客中,学习了二分搜索树:Java数据结构和算法(六)--二叉树,但是二分搜索树本身存在一个问题: 如果现在插入的数据为1,2,3,4,5,6,这样有序的数据,或者是逆序 这种情况下的二分搜索树 ...