Obtaining UI Automation Elements
This topic describes the various ways of obtaining AutomationElement objects for user interface (UI) elements.
If your client application might attempt to find elements in its own user interface, you must make all UI Automation calls on a separate thread. For more information, see UI Automation Threading Issues.
This topic contains the following sections.
All searches for AutomationElement objects must have a starting-place. This can be any element, including the desktop, an application window, or a control.
The root element for the desktop, from which all elements are descended, is obtained from the static AutomationElement.RootElement property.
In general, you should try to obtain only direct children of the RootElement. A search for descendants may iterate through hundreds or even thousands of elements, possibly resulting in a stack overflow. If you are attempting to obtain a specific element at a lower level, you should start your search from the application window or from a container at a lower level.
For most techniques you can use to retrieve UI Automation elements, you must specify a Condition, which is a set of criteria defining what elements you want to retrieve.
The simplest condition is TrueCondition, a predefined object specifying that all elements within the search scope are to be returned. FalseCondition, the converse of TrueCondition, is less useful, as it would prevent any elements from being found.
Three other predefined conditions can be used alone or in combination with other conditions: ContentViewCondition, ControlViewCondition, and RawViewCondition. RawViewCondition, used by itself, is equivalent to TrueCondition, because it does not filter elements by their IsControlElement or IsContentElement properties.
Other conditions are built up from one or more PropertyCondition objects, each of which specifies a property value. For example, a PropertyCondition might specify that the element is enabled, or that it supports a certain control pattern.
The scope defines the space around the starting-place that is to be searched. This might include the element itself, its siblings, its parent, its ancestors, its immediate children, and its descendants.
The scope of a search is defined by a bitwise combination of values from the TreeScope enumeration.
To find a known element, identified by its Name, AutomationId, or some other property or combination of properties, it is easiest to use the FindFirst method. If the element sought is an application window, the starting-point of the search can be the RootElement.
This way of finding UI Automation elements is most useful in automated testing scenarios.
To find all elements meeting specific criteria that are related to a known element, you can use FindAll. For example, you could use this method to retrieve list items or menu items from a list or menu, or to identify all controls in a dialog box.
If you have no prior knowledge of the applications that your client may be used with, you can construct a subtree of all elements of interest by using the TreeWalker class. Your application might do this in response to a focus-changed event; that is, when an application or control receives input focus, the UI Automation client examines children and perhaps all descendants of the focused element.
Another way in which TreeWalker can be used is to identify the ancestors of an element. For example, by walking up the tree you can identify the parent window of a control.
You can use TreeWalker either by creating an object of the class (defining the elements of interest by passing a Condition), or by using one of the following predefined objects that are defined as fields of TreeWalker.
Finds only elements whose IsContentElement property is true.
Finds only elements whose IsControlElement property is true.
Finds all elements.
After you have obtained a TreeWalker, using it is straightforward. Simply call the Get methods to navigate among elements of the subtree.
The Normalize method can be used for navigating to an element in the subtree from another element that is not part of the view. For example, suppose you have created a view of a subtree by using ContentViewWalker. Your application then receives notification that a scroll bar has received the input focus. Because a scroll bar is not a content element, it is not present in your view of the subtree. However, you can pass the AutomationElement representing the scroll bar to Normalize and retrieve the nearest ancestor that is in the content view.
In addition to searches and navigation, you can retrieve an AutomationElement in the following ways.
From an Event
When your application receives a UI Automation event, the source object passed to your event handler is an AutomationElement. For example, if you have subscribed to focus-changed events, the source passed to your AutomationFocusChangedEventHandler is the element that received the focus.
For more information, see Subscribe to UI Automation Events.