This documentation is archived and is not being maintained.

Invoke a Control Using UI Automation

This topic demonstrates how to perform the following tasks:

  • Find a control that matches specific property conditions by walking the control view of the UI Automation tree for the target application.

  • Create an AutomationElement for each control.

  • Obtain an InvokePattern object from any UI Automation element found that supports the InvokePattern control pattern.

  • Use Invoke to invoke the control from a client event handler.

Example

This example uses the TryGetCurrentPattern method of the AutomationElement class to generate an InvokePattern object and invoke a control by using the Invoke method.

    ///--------------------------------------------------------------------
    /// <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);
        }
    }

...

    ///--------------------------------------------------------------------
    /// <summary>
    /// Handles the Invoke click event on the client control. 
    /// The client click handler calls Invoke() on the equivalent target control.
    /// </summary>
    /// <param name="sender">The object that raised the event.</param>
    /// <param name="e">Event arguments.</param>
    /// <remarks>
    /// The Tag property of the FrameworkElement, the client button in this 
    /// case, is used to store the InvokePattern object previously obtained 
    /// from the associated target control.
    /// </remarks>
    ///--------------------------------------------------------------------
    void Invoke_Click(object sender, RoutedEventArgs e)
    {
        Button clientButton = sender as Button;
        InvokePattern targetInvokePattern = clientButton.Tag as InvokePattern;
        if (targetInvokePattern == null)
            return;
        targetInvokePattern.Invoke();
        statusText.Text = "Button invoked.";
    }

See Also

Show: