Click here to Skip to main content
15,879,535 members
Articles / Desktop Programming / WPF

WPF UI Automation

Rate me:
Please Sign up or sign in to vote.
4.50/5 (47 votes)
20 Feb 2009CPOL5 min read 242.7K   7K   88   36
This article demonstrates how to create a simple Windows UI Automation application.

Introduction

Overview

Microsoft UI Automation is the new Accessibility framework for Microsoft Windows, available on all Operating Systems that support the Windows Presentation Foundation (WPF). UI Automation provides programmatic access to most user interface (UI) elements on the desktop.

This article demonstrates how to use UI automation to control a simple application. Basically, the controller application will search for a test application which is running, and if the application is found, we will search through the UI elements hierarchy, and we will send dummy data.

Applies to:

  • Microsoft® .NET Framework 3.0
  • Microsoft® Windows Presentation Foundation - WPF
  • Microsoft® UI Automation Framework
Controller Application

UI_Automation_Controller.png

Test Application

UI_Automation_Test.png

UI Automation Framework

The main idea behind this framework is that it provides access to the hierarchy of user interface elements which are visible in Win applications. Imagine the root element of the hierarchy as being the desktop, and all the running applications are the first level nodes (children) of the root, and the same for each visible form which can be detailed to its controls, the controls to its children, and so on. Each node in this tree is called UI element.

The framework helps us by giving access to these UI elements and their properties. The main features supported by this framework are:

  • Search support, that lets you find the required user interface component.
  • Filtering the tree structure of elements; for example when querying the hierarchy of elements, we can get only the enabled controls.
  • Lets you interact with UI elements; for example, you may programmatically click a button(which is contained in a different application), from your application.
  • Subscribing to events; this helps us to monitor UI elements and handle external events.

UI Automation API

System.Windows.Automation is the main namespace of the UI Automation framework, and provides support for interacting with UI elements, also called AutomationElements. AutomationElement is the main class of the framework, and corresponds to a user interface component (window, list, button,...). The main features of this namespace are related to searching for AutomationElement objects, interacting with different control patterns or subscribing for UI automation events.

AutomationElement contains a property called RootElement, which contains a reference to the correspondent UI element of the desktop, which in fact returns an AutomationElement.

As for the search support, AutomationElement class contains FindFirst() and FindAll() methods:

C#
public AutomationElement FindFirst(TreeScope scope, Condition condition)

We can use the FindFirst method to search for a specific AutomationElement which matches the criteria passed. In order to call this method, we need to pass the scope of search (instance of TreeScope enum), for example to search through the first level of children, or to search through all descendants. Besides scope parameter, we have to pass the condition that should be met in order to identify the required AutomationElement. We will pass the condition as an instance of a class that extends Condition abstract class. In this way, we can use PropertyCondition (for testing a property to have a specific value), but also available are: AndCondition, NotCondition or OrCondition classes.

C#
public AutomationElementCollection FindAll(TreeScope scope, Condition condition);

Similar to FindFirst, FindAll() let us query the UI Automation tree using the parameters described above, but return a collection of AutomationElements that have passed the search condition.

Based on the above details, we can write a simple line of code, which will search through all the descendants of the root element, for a UI element that has the name equals to 'Notepad':

C#
AutomationElement appElement = AutomationElement.RootElement.FindFirst
(TreeScope.Descendants,new PropertyCondition(AutomationElement.NameProperty, "Notepad"))

The Implementation

In order to use the UI Automation API, we need to add references to these assemblies:

  • UIAutomationClient.dll
  • UIAutomationTypes.dll

For this simple implementation, I used the base class AutomationElement, which, as I said earlier, keeps the reference to a UI element from desktop applications. The idea is that we need to start from the desktop element, which is the root element, AutomationElement.RootElement, and we will search through all the child objects of RootElement for a test application having the title: "UI Automation Test Window". After getting a valid reference to the AutomationElement of the test application, we can then interact with the different contained controls. In this way, the controller application sets some values to two TextBox controls.

AutomationElementHierarchi.png

C#
AutomationElement rootElement = AutomationElement.RootElement;
if (rootElement != null)
{
    Automation.Condition condition = new PropertyCondition
        (AutomationElement.NameProperty, "UI Automation Test Window");

    AutomationElement appElement = rootElement.FindFirst(TreeScope.Children, condition);

    if (appElement != null)
    {
        AutomationElement txtElementA = GetTextElement(appElement, "txtA");
        if (txtElementA != null)
        {
            ValuePattern valuePatternA = 
              txtElementA.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
            valuePatternA.SetValue("10");
        }

        AutomationElement txtElementB = GetTextElement(appElement, "txtB");
        if (txtElementA != null)
        {
            ValuePattern valuePatternB = 
              txtElementB.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
            valuePatternB.SetValue("5");
        }
    }

Here is the GetTextElement function:

C#
private AutomationElement GetTextElement(AutomationElement parentElement, string value)
{
    Automation.Condition condition = 
      new PropertyCondition(AutomationElement.AutomationIdProperty, value);
    AutomationElement txtElement = parentElement.FindFirst
                (TreeScope.Descendants, condition);
    return txtElement;
}

As you can see in the above code, we are using a control pattern, ValuePattern. UIA (UI Automation) uses control patterns to represent common controls. Control patterns define the specific functionality that is available in a control by providing methods, events, and properties. The methods declared in a control pattern allow the UIA clients to manipulate the control, for example, the ValuePattern.SetValue() method. Besides ValuePattern which represents a control that stores a string value, as a different example of control pattern, we can take the Invoke pattern control, InvokePattern, which represents the controls that are invokable, controls like buttons. In order to use a control pattern, we need to query the object to see what interfaces are supported, and only after getting a valid control pattern can we interact with it by using its methods, events, and properties. The following list shows the most common control patterns:

  • SelectionPattern - used for controls that support selection, controls like ListBox, ComboBox
  • TextPattern - used for edit controls
  • ValuePattern - used to get/set a value on a control that does not support multiple values
  • InvokePattern - used for invokable controls
  • ScrollPattern - used for controls that have scrollbars
  • RangeValuePattern - used for controls that have a range of values

The following example shows how to use a InvokePattern; in other words, it will click a button contained in parentElement:

C#
{
    Automation.Condition condition = new PropertyCondition
            (AutomationElement.AutomationIdProperty, "Button1");
    AutomationElement btnElement = parentElement.FindFirst
            (TreeScope.Descendants, condition);
    
    InvokePattern btnPattern = 
    btnElement.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
    btnPattern.Invoke();
}

Conclusion

UI Automation is a powerful Accessibility framework which lets you control other applications. It can be used in the development of automated UI testing/debugging apps and so on.

There is more to come on this subject.

History

  • 4th February, 2009: Initial post
  • 5th February, 2009: Article updated
  • 19th February, 2009: Article text updated

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Romania Romania
TC is a passionate software engineer who lives & implements software technologies in Ireland.

Comments and Discussions

 
Questionerror message Pin
Member 1341959711-Oct-17 18:01
Member 1341959711-Oct-17 18:01 
GeneralNice Pin
Member 1181765013-Jun-16 7:35
Member 1181765013-Jun-16 7:35 
Questionsample using Microsoft Lync Pin
srinivaslolla11-Dec-13 7:19
srinivaslolla11-Dec-13 7:19 
GeneralClear and useful Pin
Davy Sappin23-Sep-13 22:41
Davy Sappin23-Sep-13 22:41 
Questionexample with Notepad Pin
closl30-Jan-12 5:43
closl30-Jan-12 5:43 
QuestionHow to press and hold a button Pin
LaserEngraver9-Aug-11 7:41
LaserEngraver9-Aug-11 7:41 
GeneralGreat introduction, need more meat to complete the picture Pin
Avi zir1-Jun-11 3:54
Avi zir1-Jun-11 3:54 
Generalautomation in Tab controls Pin
sajithajose20-May-11 0:49
sajithajose20-May-11 0:49 
in my WPF application, i am using this automation framework. If i open more than one TAB item then it is unable to identify controls. Do you know why it is so?
GeneralWhich control pattern ( automation pattern) should be used for chart control [modified] Pin
Member 792989016-May-11 21:27
Member 792989016-May-11 21:27 
GeneralComboBox Pin
Member 78016054-Apr-11 21:40
Member 78016054-Apr-11 21:40 
GeneralContextMenu Pin
Sharan Jadhav16-Mar-11 7:43
Sharan Jadhav16-Mar-11 7:43 
GeneralMy vote of 5 Pin
Mahmudul Haque Azad22-Feb-11 21:24
Mahmudul Haque Azad22-Feb-11 21:24 
GeneralExcellent Introduction!!!! Thanks! Pin
Your Display Name Here1-Dec-10 1:16
Your Display Name Here1-Dec-10 1:16 
GeneralMy vote of 4 Pin
guccyme18-Jul-10 21:27
guccyme18-Jul-10 21:27 
QuestionWhat's with all the 2 ratings? Pin
rittjc25-Jun-10 18:51
rittjc25-Jun-10 18:51 
QuestionSelecting item from list view Pin
meshilpa3-Apr-10 1:49
meshilpa3-Apr-10 1:49 
AnswerRe: Selecting item from list view Pin
rittjc25-Jun-10 19:14
rittjc25-Jun-10 19:14 
GeneralRe: Selecting item from list view Pin
Michael Katsarakis17-Oct-10 6:41
Michael Katsarakis17-Oct-10 6:41 
GeneralQuestion about UI Automation Pin
y_h_hsu8-Mar-10 23:03
y_h_hsu8-Mar-10 23:03 
GeneralRe: Question about UI Automation Pin
Calin Tatar11-Mar-10 11:30
Calin Tatar11-Mar-10 11:30 
GeneralContextmenu Pin
BAALBERT9-Jun-09 6:28
BAALBERT9-Jun-09 6:28 
AnswerRe: Contextmenu Pin
rittjc25-Jun-10 19:28
rittjc25-Jun-10 19:28 
GeneralThx. Pin
David Catriel5-Jun-09 8:19
David Catriel5-Jun-09 8:19 
General[Message Deleted] Pin
Jammer19-Feb-09 11:14
Jammer19-Feb-09 11:14 
GeneralRe: Just Crashes ... Pin
Calin Tatar19-Feb-09 11:35
Calin Tatar19-Feb-09 11:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.