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. webpack中所使用到的npm常用命令

    :D进入D盘 mkdir webapp 创建webapp文件夹 cd webapp 进入webapp文件夹 mkdir webapp && cd webapp 以上两步创建和进入文件夹 ...

  2. get请求中文乱码

    get请求时要将url进行encodeURI http://www.ruanyifeng.com/blog/2010/02/url_encoding.html http://www.ruanyifen ...

  3. myeclipse 配置svn

    方法三:直接解压下载SVN插件:site-1.6.10.zip解压后将其全部文件拷贝至:D:\Program Files\Genuitec\MyEclipse 8.5\dropins(MyEclips ...

  4. Java虚拟机系列(二)---HotSpot虚拟机对象

    都知道Java是一门面向对象的编程语言,在Java程序运行过程中,无时无刻不在创建对象,所以这节来总结一下HotSpot虚拟机中的Java对象. 一.Java虚拟机对象的创建过程. 在语义层面创建一个 ...

  5. Java虚拟机系列(一)---Java内存划分

    Java和C++之间有一堵由内存管理和垃圾收集技术所围成的“高墙”,墙外的人想进去,墙内的人却想出来.  ------摘自<深入理解Java虚拟机> 作为一个Java程序员,因为虚拟机的好 ...

  6. Redis学习03——存储字符串(String)

    --------------------- 作者:愤怒的小明 来源:CSDN 原文:https://blog.csdn.net/qiwenmingshiwo/article/details/78118 ...

  7. Acesrc and Travel

    Acesrc and Travel 时间限制: 1 Sec  内存限制: 128 MB 题目描述 Acesrc is a famous tourist at Nanjing University se ...

  8. Luogu P4011 孤岛营救问题(状态压缩+最短路)

    P4011 孤岛营救问题 题意 题目描述 \(1944\)年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到 ...

  9. 非常好理解的KNN算法示例

    参考链接:https://www.joinquant.com/post/2227?f=study&m=math:一只兔子帮你理解KNN https://www.joinquant.com/po ...

  10. SSM-6nginx Linux下的安装

    1.下载nginx: 官方网站: http://nginx.org/download/ 2. 要求的安装环境 yum install gcc-c++ yum -y install pcre-devel ...