Obtaining UI Automation Elements
Note
This documentation is intended for .NET Framework developers who want to use the managed UI Automation classes defined in the System.Windows.Automation namespace. For the latest information about UI Automation, see Windows Automation API: UI Automation.
This topic describes the various ways of obtaining AutomationElement objects for user interface (UI) elements.
Caution
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.
Root Element
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.
Caution
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.
Conditions
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.
Conditions can be combined using Boolean logic by constructing objects of types AndCondition, OrCondition, and NotCondition.
Search Scope
Searches done by using FindFirst or FindAll must have a scope as well as a starting-place.
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.
Finding a Known Element
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.
Finding Elements in a Subtree
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.
Walking a Subtree
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.
Field | Description |
---|---|
ContentViewWalker | Finds only elements whose IsContentElement property is true . |
ControlViewWalker | Finds only elements whose IsControlElement property is true . |
RawViewWalker | 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.
Other Ways to Retrieve an Element
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.
From a Point
If you have screen coordinates (for example, a cursor position), you can retrieve an AutomationElement by using the static FromPoint method.
From a Window Handle
To retrieve an AutomationElement from an HWND, use the static FromHandle method.
From the Focused Control
You can retrieve an AutomationElement that represents the focused control from the static FocusedElement property.