TreeWalker and FindAll function[转贴]

http://www.automationspy.com/post-25_12_2014.html

Get all control children of an element using AutomationElement.FindAll function:

 1 // using FindAll function
 2 private List<AutomationElement> GetChildren(AutomationElement parent)
 3 {
 4     if (parent == null)
 5     {
 6         // null parameter
 7         throw new ArgumentException();
 8     }
 9     AutomationElementCollection collection = parent.FindAll(TreeScope.Children, Condition.TrueCondition);
10     if (collection != null)
11     {
12         List<AutomationElement> result = new List<AutomationElement>(collection.Cast<AutomationElement>());
13         return result;
14     }
15     else
16     {
17         // some error occured
18         return null;
19     }
20 }

Get control children of an element using the predefined TreeWalker.ControlViewWalker:

// using predefined TreeWalker.ControlViewWalker
private List<AutomationElement> GetChildren(AutomationElement parent)
{
    if (parent == null)
    {
        // null parameter
        throw new ArgumentException();
    }
    List<AutomationElement> result = new List<AutomationElement>();
    // the predefined tree walker wich iterates through controls
    TreeWalker tw = TreeWalker.ControlViewWalker;
    AutomationElement child = tw.GetFirstChild(parent);
    while (child != null)
    {
        result.Add(child);
        child = tw.GetNextSibling(child);
    }
    return result;
}

Get the same result using a custom TreeWalker:

 1 // using customized TreeWalker
 2 private List<AutomationElement> GetChildren(AutomationElement parent)
 3 {
 4     if (parent == null)
 5     {
 6         throw new ArgumentException();
 7     }
 8     List<AutomationElement> result = new List<AutomationElement>();
 9     PropertyCondition condition = new PropertyCondition(AutomationElement.IsControlElementProperty, true);
10     TreeWalker tw = new TreeWalker(condition);
11     AutomationElement child = tw.GetFirstChild(parent);
12     while (child != null)
13     {
14         result.Add(child);
15         child = tw.GetNextSibling(child);
16     }
17     return result;
18 }

MS UI Automation has two ways of navigating through collections of elements and hierarchies. One is by using FindAll function and can be used to obtain the entire collection or a subset of children/descendants of an Automation Element and the second way is by using TreeWalker. Both ways support search filtering by element properties. TW offers a lot more search features and navigation features like moving to first child, moving to last child, moving to next sibling of a specified element and moving to Parent.

What is the connection between TreeWalker and FindAll function? FindAll is the same with using the predefined tree walker TW.ControlViewWalker and moving from the first child to the last child. So, FindAll function returns only control elements.

There are 2 other predefined tree walkers: RawViewWalker and ContentViewWalker. RawViewWalker gets all the elements and ContentViewWalker gets elements marked as content elements.

If you are using a similarity between TW.RawViewWalker or TW.ContentViewWalker and FindAll function you may find some incompatibilities meaning that you may find some Automation elements in one collection that don‘t have correspondents in the other collection. I think FindAll function can be used safely with TW.ControlViewWalker as 1-1.

Why to use FindAll and why to use TreeWalker or why not always to use TreeWalker? Microsoft says FindAll function works faster than TreeWalker for some kinds of applications, like WPF applications, and TreeWalker works faster for Win32 controls. Could be, but the difference of speed may not be so big as you expect. FindAll function has also the advantage of making things easy when you want to search through the entire collection of descendants. TreeWalker can also be used to search through the collection of descendants (recursively), but with more code and less efficiency.

Working with UI Automation may be challenging when using large collections of children or descendants and especially when using filtering criteria because these kinds of actions can be very time-consuming. So, understanding how to work with collections and navigating through hierarchies of elements is a big step in starting development with Microsoft UI Automation.

时间: 2024-10-26 01:43:28

TreeWalker and FindAll function[转贴]的相关文章

基于json数据格式实现的简单数据库——jsonDB

已在github上建立项目:https://github.com/ThinkerCodeChina/jsonDB /** +----------------------------------------- * jsonDB 基于json数据格式构建的数据模型 +----------------------------------------- * @description 对json数据检索,删除,查询和更新 * @author 戚银(web程序员) [email protected] * @

【JAVAWEB学习笔记】网上商城实战2:异步加载分类、Redis缓存分类和显示商品

网上商城实战2 今日任务 完成分类模块的功能 完成商品模块的功能 1.1      分类模块的功能: 1.1.1    查询分类的功能: 1.1.2    查询分类的代码实现: 1.1.2.1  创建表: CREATE TABLE `category` ( `cid` varchar(32) NOT NULL, `cname` varchar(20) DEFAULT NULL, PRIMARY KEY (`cid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 1

Backbone的localStorage.js源码详细分析

Backbone.localStorage.js是将数据存储到游览器客户端本地的(当没有服务器的情况下) 地址:https://github.com/jeromegn/Backbone.localStorage 1     整个函数是一个自执行函数,简化版形式如下 (function(a,fn) { //... })(a,fn); 2     9-12行/**---------此处是判断上下文有没有引入AMD模块(如requirejs)-----------*/ if(typeofdefine=

node的实践(项目二)

找以前看看简单的demo,看看node是怎么操作Mongo然后又是渲染前台的,与前面的项目一中的对比. 1.操作Mongo数据库的方法和方式. var mongodb = require('./db'), markdown = require('markdown').markdown; function Post(name, head, title, tags, post) { this.name = name; this.head = head; this.title = title; thi

prototype.js 源码解读(02)

如果你想研究一些比较大型的js框架的源码的话,本人建议你从其最初的版本开始研读,因为最初的版本东西少,易于研究,而后的版本基本都是在其基础上不断扩充罢了,所以,接下来我不准备完全解读prototype.js的源码了,而是拿它一些常见的API来解读. //定时器类,比起window.setInterval函数,该类能够使得回调函数不会被并发调用 var PeriodicalExecuter = Class.create();//Class类创建的定时器类 PeriodicalExecuter.pr

深入浅出EF之ModelFirst和DBFirst

在上篇博文中,小编主要简单的介绍了一下EF的一些基础知识,其中,小编蜻蜓点水的提了一下ModelFirst和DBFirst,ModelFirst先设计实体,然后根据模型生成数据库,DBFirst根据数据库生成模型,两个方向都是可以了,两个方向可以相互更新,比如新添加了实体,可以根据模型生成数据库,如果在数据库里面新添加了字段,我们可以从数据库更新模型.在介绍ModelFirst和DBFirst之前,我们先来解决两个问题,EF与linq to sql的关系以及为什么使用linq to sql和EF

[Baidu Map]百度地图 JAVASCRIPT API V2.0 大众版 工具类

关键代码: /* *@description 百度地图 JAVASCRIPT API V2.0 大众版 工具类 *@author YanZhiwei *@see http://developer.baidu.com/map/reference/index.php *@email [email protected] */ (function () { map = {}; infoWindow = {}; BmapUtils = { CONSTANT: { DYNAMIC_CITY: "上海&quo

AngularJS 与liferay对接

AngularJS与liferay对接 1.新建一个liferay plugin project 项目: 2.在新建liferay项目docroot目录下新建html目录,拷贝AngularJS项目app文件到html目录下: 3.修改view.jsp文件,增加document.getPortletUrl函数,用angular.bootstrap启动angularjs: 代码如下: 3.1 加载css文件方式:@import url(); 3.2 加载JS文件方式不变:<script><

indexedDB bootstrap angularjs之 MVC Demo

前端之MVC应用 1.indexedDB(Model) -- 前端浏览器对象型数据库,一般我们后台用的数据库都是关系型数据库.那么indexeddb有什么特点呢: 首先,从字义上它是索引型数据库,从实际使用中可以体现为,它需要为表创建索引才可以根据某个字段来获取数据,而在关系型数据库中,这明显是不需要的. 其次,我不需要行列数据的转化,我只需要通过类似于数组的处理方式: objectStore.push(data); 有点像是把一个json对象塞入数据库,是不是很暴力? 2.bootstrap(