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实现高效率的视觉对象搜索的更多相关文章

  1. Power BI 可视化交互/视觉对象交互

    xx Power BI的官方文档特别好,但是具体到自己使用的时候,有些知识点,可能看完文档忘了,导致有些功能做不出来...网络上资料还比较匮乏... 自己没事还是多总结下吧... 比如: 文档上写的很 ...

  2. 搜索分析(DFS、BFS、递归、记忆化搜索)

    搜索分析(DFS.BFS.递归.记忆化搜索) 1.线性查找 在数组a[]={0,1,2,3,4,5,6,7,8,9,10}中查找1这个元素. (1)普通搜索方法,一个循环从0到10搜索,这里略. (2 ...

  3. poj1753 bfs+奇偶性减枝//状压搜索

    http://poj.org/problem?id=1753 题意:有个4*4的棋盘,上面摆着黑棋和白旗,b代表黑棋,w代表白棋,现在有一种操作,如果你想要改变某一个棋子的颜色,那么它周围(前后左右) ...

  4. hdu1428漫步校园( 最短路+BFS(优先队列)+记忆化搜索(DFS))

    Problem Description LL最近沉迷于AC不能自拔,每天寝室.机房两点一线.由于长时间坐在电脑边,缺乏运动.他决定充分利用每次从寝室到机房的时间,在校园里散散步.整个HDU校园呈方形布 ...

  5. 用BFS和DFS解决圆盘状态搜索问题

    人工智能课程的实验(我的解法其实更像是算法课程的实验) 用到的算法:深度优先搜索.宽度优先搜索(状态扩展的不同策略) 数据结构:表示状态的结构体.多维数组 (可能是最近做算法竞赛题的影响,这次并不像以 ...

  6. BFS(一):广度优先搜索的基本思想

    广度优先搜索BFS(Breadth First Search)也称为宽度优先搜索,它是一种先生成的结点先扩展的策略. 在广度优先搜索算法中,解答树上结点的扩展是按它们在树中的层次进行的.首先生成第一层 ...

  7. 《纵向切入ASP.NET 3.5控件和组件开发技术》笔记:高效率事件集合对象

    在之前讲的几个例子中,使用的是最普通的定义事件方法,比如KingTextBox中事件是这样定义的:/// <summary>/// 获得本书更多内容,请看:/// http://blog. ...

  8. AOJ 0121: Seven Puzzle【BFS】

    From: AOJ 0121 思路:与前几题的bfs不同,这次的bfs没有明确的移动对象,看似任意一个数都可以当成对象移动.这时我们只需要抓住一个格子就行,比如我们把0作为移动对象,那么0在地图中漫游 ...

  9. 数据结构之DFS与BFS实现

    本文主要包括以下内容 邻接矩阵实现无向图的BFS与DFS 邻接表实现无向图的BFS与DFS 理论介绍 深度优先搜索介绍 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似 ...

随机推荐

  1. windwos API 第七篇 分离路径,组合路径 _splitpath _makepath

    函数原型: //Break a path name into components. void _splitpath( const char *path, char *drive, char *dir ...

  2. 转:步步LINUX C--进程间通信(二)信号

    源地址:http://blog.csdn.net/jmy5945hh/article/details/7529651 linux间进程通信的方法在前一篇文章中已有详细介绍.http://blog.cs ...

  3. 转载 Python 安装setuptools和pip工具操作方法(必看)

    本文章转载自 脚本之家 http://www.jb51.net  感谢! setuptools模块和pip模块是python进行第三方库扩展的极重要工具,例如我们在需要安装一些爬虫或者数据分析的包时就 ...

  4. jmeter参数化之用户自定义变量

    1.     用badboby进行录制,录制完成后保存,用JMeter格式进行保存,如:登陆.jmx 2.     在jmeter中打开保存的文件登陆.jmx. 3.线程组右击-添加-配置元件-用户定 ...

  5. 洛谷P4244 [SHOI2008]仙人掌图 II

    传送门 首先不考虑带环的仙人掌,如果只是一棵普通的树,可以通过dp求每棵子树中的最长链和次长链求树的直径. 那么如果dfs的时候遇到了环,应该用环上的两点挂着的最长链加上两点间的距离来更新树的直径,并 ...

  6. 卸载VS2015之后,安装VS2017出错

    安装出现问题. 可通过以下方式排查包故障问题: 1. 使用以下搜索 URL 来搜索针对每个包故障的解决方案 2. 针对受与影响的工作负荷或组件修改选项,然后重新尝试安装 3. 从计算机上删除产品,然后 ...

  7. 查看cpu性能和磁盘空间

    df -h查看当前磁盘空间 du -sh查看当前目录占用的磁盘空间 du -sh * 查看当前所有目录占用的磁盘空间   lscpu查看cpu信息 free查看空间总量

  8. mybatis学习:mybatis注解开发一对一的查询配置

    实体类: public class Account { private Integer id; private Integer uid; private Double money; private U ...

  9. py3.x和py2.x的区别

    1.性能 Py3.0运行 pystone benchmark的速度比Py2.5慢30%.Guido认为Py3.0有极大的优化空间,在字符串和整形操作上可 以取得很好的优化结果. Py3.1性能比Py2 ...

  10. Luogu P1948 [USACO08JAN]电话线Telephone Lines(最短路+dp)

    P1948 [USACO08JAN]电话线Telephone Lines 题意 题目描述 Farmer John wants to set up a telephone line at his far ...