Find a UI Automation Element Based on a Property Condition
This topic contains example code that shows how to locate an element within the UI Automation tree based on a specific property or properties.
In the following example, a set of property conditions are specified that identify a certain element (or elements) of interest in the AutomationElement tree. A search for all matching elements is then performed with the FindAll method that incorporates a series of AndCondition boolean operations to limit the number of matching elements.
Note: |
|---|
When searching from the RootElement, you should try to obtain only direct children. A search for descendants might 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. |
///-------------------------------------------------------------------- /// <summary> /// Walks the UI Automation tree of the target and reports the control /// type of each element it finds in the control view to the client. /// </summary> /// <param name="targetTreeViewElement"> /// The root of the search on this iteration. /// </param> /// <param name="elementIndex"> /// The TreeView index for this iteration. /// </param> /// <remarks> /// This is a recursive function that maps out the structure of the /// subtree of the target beginning at the AutomationElement passed in /// as the rootElement on the first call. This could be, for example, /// an application window. /// CAUTION: Do not pass in AutomationElement.RootElement. Attempting /// to map out the entire subtree of the desktop could take a very /// long time and even lead to a stack overflow. /// </remarks> ///-------------------------------------------------------------------- private void FindTreeViewDescendants( AutomationElement targetTreeViewElement, int treeviewIndex) { if (targetTreeViewElement == null) return; AutomationElement elementNode = TreeWalker.ControlViewWalker.GetFirstChild(targetTreeViewElement); while (elementNode != null) { Label elementInfo = new Label(); elementInfo.Margin = new Thickness(0); clientTreeViews[treeviewIndex].Children.Add(elementInfo); // Compile information about the control. elementInfoCompile = new StringBuilder(); string controlName = (elementNode.Current.Name == "") ? "Unnamed control" : elementNode.Current.Name; string autoIdName = (elementNode.Current.AutomationId == "") ? "No AutomationID" : elementNode.Current.AutomationId; elementInfoCompile.Append(controlName) .Append(" (") .Append(elementNode.Current.ControlType.LocalizedControlType) .Append(" - ") .Append(autoIdName) .Append(")"); // Test for the control patterns of interest for this sample. object objPattern; ExpandCollapsePattern expcolPattern; if (true == elementNode.TryGetCurrentPattern(ExpandCollapsePattern.Pattern, out objPattern)) { expcolPattern = objPattern as ExpandCollapsePattern; if (expcolPattern.Current.ExpandCollapseState != ExpandCollapseState.LeafNode) { Button expcolButton = new Button(); expcolButton.Margin = new Thickness(0, 0, 0, 5); expcolButton.Height = 20; expcolButton.Width = 100; expcolButton.Content = "ExpandCollapse"; expcolButton.Tag = expcolPattern; expcolButton.Click += new RoutedEventHandler(ExpandCollapse_Click); clientTreeViews[treeviewIndex].Children.Add(expcolButton); } } TogglePattern togPattern; if (true == elementNode.TryGetCurrentPattern(TogglePattern.Pattern, out objPattern)) { togPattern = objPattern as TogglePattern; Button togButton = new Button(); togButton.Margin = new Thickness(0, 0, 0, 5); togButton.Height = 20; togButton.Width = 100; togButton.Content = "Toggle"; togButton.Tag = togPattern; togButton.Click += new RoutedEventHandler(Toggle_Click); clientTreeViews[treeviewIndex].Children.Add(togButton); } InvokePattern invPattern; if (true == elementNode.TryGetCurrentPattern(InvokePattern.Pattern, out objPattern)) { invPattern = objPattern as InvokePattern; Button invButton = new Button(); invButton.Margin = new Thickness(0); invButton.Height = 20; invButton.Width = 100; invButton.Content = "Invoke"; invButton.Tag = invPattern; invButton.Click += new RoutedEventHandler(Invoke_Click); clientTreeViews[treeviewIndex].Children.Add(invButton); } // Display compiled information about the control. elementInfo.Content = elementInfoCompile; Separator sep = new Separator(); clientTreeViews[treeviewIndex].Children.Add(sep); // Iterate to next element. // elementNode - Current element. // treeviewIndex - Index of parent TreeView. FindTreeViewDescendants(elementNode, treeviewIndex); elementNode = TreeWalker.ControlViewWalker.GetNextSibling(elementNode); } }
Note: