(Lviv community of .NET developers)

UI Automation overview (Part II)

September 12, 2007 04:47 by fors

Introduction

In this part we will closely examine such fundamentals of UI Automation as:

  • UI Automation control patterns
  • UI Automation properties
  • UI Automation events

And in the end, we will try to implement a simple UI Automation support for custom control.


Advertisement
Public Folder Watcher (PFW) is an add-on for Microsoft Outlook enabling support of notifications about changes in Exchange Public Folders and providing a status of unread email messages.

UI Automation control patterns

UI Automation control paterns provide a uniform approach to structure and express control's functionality. Microsoft identified the 18 control patterns, which represent everything that can be done with UI elements. For example, you can use Invoke control pattern for controls that can be invoked (such as buttons ) or Text pattern for edit controls and documents that expose textual information. There is no unique identification between patterns and controls, one pattern can belong to different controls as well as one control can support several pattrens. For example: ComboBox supports ExpandCollapse and Selection patterns. So combining these 18 control patterns, developers can represent the full range of functionality for any user of UI element.

        Control Patterns and their Classes and Interfaces

Control Pattern Client-Side Class Provider-Side Interfaces
Dock DockPattern IDockProvider
ExpandCollapse ExpandCollapsePattern IExpandCollapseProvider
Grid GridPattern IGridProvider
GridItem GridItemPattern IGridItemProvider
Invoke InvokePattern IInvokeProvider
MultipleView MultipleViewPattern IMultipleViewProvider
RangeValue RangeValuePattern IRangeValueProvider
Scroll ScrollPattern IScrollProvider
ScrollItem ScrollItemPattern IScrollItemProvider
Selection SelectionPattern ISelectionProvider
SelectionItem SelectionItemPattern ISelectionItemProvider
Table TablePattern ITableProvider
TableItem TableItemPattern ITableItemProvider
Text TextPattern ITextProvider
Toggle TogglePattern IToggleProvider
Transform TransformPattern ITransformProvider
Value ValuePattern IValueProvider
Window WindowPattern IWindowProvider

 

Providers implement control pattern interfaces on UI elements. Control pattern interfaces are found in the System.Windows.Automation.Provider namespace and have names that include the suffix "Provider" (for example, IScrollProvider and IInvokeProvider ).
Clients access methods and properties of control pattern classes and use them to access information about a UI element, or to manipulate the UI. These control patterns classes are found in the Systems.Windows.Automation namespace and have names that include the suffix "Pattern" (for example, InvokePattern and SelectionPattern ).
Control patterns combine into one: structure, methods, properties and events supported by control. Control patterns relate to UI as interfaces relate to COM objects. In COM, you can query an object to ask what interfaces it supports, and then use those interfaces to access functionality. In UI Automation, clients can ask a control which patterns it supports and then interact with the control through the properties, methods, events, and structure of the supported control patterns. For example, providers implement IScrollProvider for a multi-line edit box. When a client detects that a UI element supports ScrollPattern, it can use the properties, methods, and events from that class to gather scroll-specific information or programmatically scroll its content to a new position.
Here is a small part of code that shows how to use InvokePattern
For example, we want to Invoke "Start" button. At first we need to find it and cast to AutomationElement, then to obtain its InvokePatterrn an call Invoke method:

 
AutomationElement start = null;   PropertyCondition conds = 
new PropertyCondition( AutomationElement.NameProperty, "start" );    start = AutomationElement.RootElement.FindFirst( TreeScope.Descendants, conds );   if( start != null )   {      InvokePattern startInvoke = 
   (InvokePattern)start.GetCurrentPattern( InvokePattern.Pattern );      startInvoke.Invoke();   }
 

UI Automation properties

UI Automation properties are a set of standard properties that expose information, such as Name, ControlType, Orientation, AccessKey, etc., that is important to assistive technologies. These properies give an opportunity for UI Automation Client application to discover information about different parts of UI. UI Automation properties are read-only. To set properties of a control, you have to use the methods of the appropriate control pattern. Also, as you may notice from the previous code: properties (property ID's) are used in constructing PropertyCondition objects used to find AutomationElement objects. In that way you can specify (by Name, by Type, by Process Id, etc.) what kind of UI element you want to find.

The following code example shows two ways of retrieving a property on an AutomationElement.

 
// elementUI is an AutomationElement. // The following two calls are equivalent. string strName = elementUI.Current.HelpText;   strName = 
elementUI.GetCurrentPropertyValue(AutomationElement.HelpTextProperty) as string;

To improve performance, property values of controls and control patterns can be cached when AutomationElement objects are retrieved. In UI Automation, caching means that the data can then be accessed without further cross-process communication. So you can get Current or Cached equivalent of property value or control pattern. For the most part, caching - is an automated processs, but there are also special classes and methods that allow caching manipulations . The benefits of caching are most noticeable with WPF controls and custom controls that have server-side UI Automation providers. There is less benefit when accessing client-side providers such as the default providers for Win32 controls.
For different UI Frameworks the same UI Automation property can expose different native framework properties. The following table shows how one standard UI Automation property maps to multiple property names in other UI frameworks.

Mapping UI Automation Properties to Other UI Frameworks

UI Automation Control Type UI Framework Framework Property UI Automation Property
Button Avalon Content NameProperty
Button Win32 Caption NameProperty
Image HTML ALT NameProperty

 

By implementing UI Automation, providers should map unique UI framework properties to standard UI Automation properties.

UI Automation events

UI Automation provides information to client applications through events. Unlike WinEvents, UI Automation events are not based on a broadcast mechanism. Clients register for specific event notifications and can request that specific UI Automation properties and control pattern information be passed into their event handler. Providers can improve performance by raising events selectively, depending on whether any clients are subscribed to those events, or not.

UI Automation events fall into the following categories

Event Description
Property change Raised when a property on an UI Automation element or control pattern changes. For example, if a client needs to monitor an application's check box control, it can register to listen for a property change event on the ToggleState property. When the check box control is checked or unchecked, the provider raises the event and the client can act as necessary.
Element action Raised when a change in the UI results from end user or programmatic activity; for example, when a button is clicked or invoked through InvokePattern
Structure change Raised when the structure of the UI Automation tree changes. The structure changes when new UI items become visible, hidden, or removed on the desktop.
Global desktop change Raised when actions of global interest to the client occur, such as when the focus shifts from one element to another, or when a window closes.

 

Here is an example on how to track Start button Invoke event:

//start is AutomationElement.that represents Start button   //Register an event handler for InvokedEvent on the start button. Automation.AddAutomationEventHandler(InvokePattern.InvokedEvent,
start,TreeScope.Element, new AutomationEventHandler(OnStartInvoke));     //Event handler private void OnStartInvoke( object src, AutomationEventArgs e )   {                  MessageBox.Show( "Start has been invoked" );   }
 

Implementing UI Automation support

This is a small tutorial about how to provide an UI Autoamtion support for custom WPF control. To demonstrate this, I have created two custom buttons (SimpleButton and SimpleButton2) with 3D effect click. This two controls are identional, but one of them supports UI Automation(SimpleButton) and another(SimpleButton2) does not. I've done it, to show that control with UI Automation support can be recognized by accesibility programs, and another one that does not provide UI Automation support can not.

Note:To feel all details of implementing UI Automation support, it is very important that control should be derived from low - hierarchy class (like Control or ContentControl) and would not have a standard WPF control inside its template. Because standard WPF controls support UI Automation by default.

Microsoft gives a special requirements (such as tree structure, properties, supported patterns, etc ) necessary for correct UI Automation implementation. You can find them here

Custom WPF controls provide UI Automatiom support through AutomationPeer class or derived from it. There are also nany specialized classes such as: ButtonAutomationPeer CheckBoxAutomationPeer, etc. But as our SimpleButton derives from ContentControl class our peer class will be derived from FrameworkElementAutomationPeer. The good rule is to name it SimpleButtonAutomationPeer (control name + "AutomationPeer").
Here is an implementation of SimpleButtonAutomationPeer:

#region UI Automation support    //Class that provides UI Automation support public class SimpleButtonAutomationPeer : 
FrameworkElementAutomationPeer, IInvokeProvider   {       public SimpleButtonAutomationPeer( SimpleButton control )           : base( control )       {       }         protected override string GetClassNameCore()       {           return "SimpleButton";       }         protected override string GetLocalizedControlTypeCore()       {           return "button";       }         protected override AutomationControlType GetAutomationControlTypeCore()       {           return AutomationControlType.Button;       }         public override object GetPattern( PatternInterface patternInterface )       {           if( patternInterface == PatternInterface.Invoke )           {               return this;           }             return base.GetPattern( patternInterface );       }         private SimpleButton MyOwner       {           get          {              return (SimpleButton)base.Owner;           }       }       #region IInvokeProvider Members         public void Invoke()       {           RoutedEventArgs newEventArgs = 
        new RoutedEventArgs( SimpleButton.ClickEvent );           MyOwner.RaiseEvent( newEventArgs );       }       #endregion   }  #endregion

In this class we overrode some basic property getters wich are responsible for correct control identification. As our control is a button we also should support InvokePattern and or TogglePattern (see requirements) To do this, IinvokeProvider interface must be implemented. If the control supports the Invoke control pattern, then InvokeEvent must be supported too. Therefore bofore raising Click RoutedEvent, we should raise UI Automation Invoke event(see code below).

protected virtual void OnClick(){   //raising UI Automation InvokeEvent   if( AutomationPeer.ListenerExists( AutomationEvents.InvokePatternOnInvoked ) )   {     AutomationPeer peer = UIElementAutomationPeer.CreatePeerForElement( this );     if( peer != null )     {       peer.RaiseAutomationEvent( AutomationEvents.InvokePatternOnInvoked );     }   }               //raising routed event click   FireClickEvent();            }

 

And the last we should do is to override OnCreateAutomationPeer method in SimpleButton class, which returns SimpleButtonAutomationPeer object( see code below ).

 

protected override AutomationPeer OnCreateAutomationPeer()   {      return new SimpleButtonAutomationPeer( this );   }

To see the results of all this work I have created an application that contains several controls, among which there  are standard WPF controls and two our custom buttons(one with UI Atomation support, and another one - without ) . I also added a simple UI Automation explorer that builds a tree and gives some information about controls with UI Automation support, which belong to its own application.

Note: Don't forget! If you want to explore your own application user interfase, you must make all UI Automation calls from a separate thread.

Summary

At the app window you can see that MySimpleButton has an UI Automation support, therefore you can find it in the UI tree, and MySimpleButton2 (without UI Automation support) could not be detected by UI Automation system. You can also check it with UI Spy utulity.

It's a good idea to run UI Spy against your application to make sure everything is shown corectly. If an item appears incorrectly, you can manualy set the propety which provides a wrong information. You can do this in such way, for example HelpText property is incorect:

<TextBlock Name="textBox" 
AutomationProperties.HelpText="Correct help text"/>

So, no matter how good your control is, if you want to make it accessible for people with special needs, you must support UI Automation. As it was shown at the latest surveys the nuber of such people increases, therefore supporting UI Automation will improve product quality and will be a good thing in attracting clients.

References

SimpleUIAutomationSupport.zip (22,14 kb)  - demo project sources


Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: , ,
Categories: WinFx
Actions: Permalink | Comments (23) | RSSRSS comment feed

Comments

February 24. 2010 16:58

Hi

Thanks to talk about this issue. I found many info here.
Keep posting and happy blogging.

Regards
Dave

shiseido skin care

March 18. 2010 13:48

This was just what I was looking for... Thanks!

Wayne @ Overclock CPU Guide

April 7. 2010 07:36

nice post here,thanks for share!thanks again!

registry cleaner

April 16. 2010 01:33

Really informative post. I’ve discovered your blog via Google and I’m really glad about the info you offer in your articles. Btw your blogs layout is truly broken about the Kmelon browser. Will be really great if you could fix that. Anyhow keep up the good w

application essay

April 19. 2010 12:31

You have mention informative content above I really enjoy the information and learn lots. I wish to come again on your site in future…

mba institute delhi

May 3. 2010 09:05

This tutorial is very helpful to all who need it, because you&#39;ve explained perfectly and easy to understand. very pleased to be able to visit your site

alarm wiring diagram

May 13. 2010 16:25

Thanks for sharing this valid set of information with us.Thank you very much.Keep it up the good

colon cleansing reviews

May 13. 2010 16:26

You can conquer almost any fear if you will only make up your mind to do so. For remember, fear doesn't exist anywhere except in the mind.

chiropractic falls church

May 29. 2010 19:23

Interesting post :) Thanks for creating an excellent post about development. You make some brilliant points :)

water removal ponte vedra beach, fl

June 27. 2010 10:13

That is a spectacular writing which I am glad I found. I am always interestef in educational matters.

Universities

July 2. 2010 21:53

Hello! I simply wanted to say your site is one of the nicely laid out, most inspirational I've come across in quite a while. Thx! :)

Carolyn

July 6. 2010 05:37

Have no money to buy some real estate? Worry not, just because it's achievable to get the <a href="http://lowest-rate-loans.com/topics/business-loans";>business loans</a> to work out such kind of problems. Hence get a secured loan to buy everything you want.

LoriBarry22

July 7. 2010 09:41

I totally agree.

pee-l

July 7. 2010 20:44

Another good post like always a joy looking at

Peen

July 10. 2010 21:45

Trubloods.com is any internet site dedicated in order to bringing a person each a single regarding the amazing benefits because well because darkness through the struck demonstrate True Blood. True Blood is named as the particular artificial bloodstream the western possess created and now vampires associated with the underworld arise as a result of the actual darkness to attempt and coexist with human beings. A person stick to Sookie Stackhouse as she offers with the chaos which exists on earth. There is love, humor, action, and numerous more whilst a person view vampires, humans and also supernaturals conflict inside the community of Bon Temps, Louisiana. Watch free streams at trubloods.com!

supernatural

July 14. 2010 23:19

Another good post like always a joy looking at

vibram fivefingers

July 15. 2010 09:45

If you are willing to buy real estate, you would have to get the business loans. Furthermore, my sister commonly takes a financial loan, which supposes to be the most fast.

credit loans

July 18. 2010 04:46

Hi, I don't know why, but when I enter your feed into my aggregator, it's not working. the RSS URL just to make sure I'm using the right one? I appreciate it. :)

Jovita Claucherty

July 21. 2010 07:34

The successful man will profit from his mistakes and try again in a different way.

online cash loans

July 23. 2010 15:17

I finished to worry just because of my academic grades! I always buy coursework and all seems to be great.

course work writing

July 24. 2010 00:04

People live a tree for breath. wow...
http://www.nikeairjordan.cc

Rerto Jordans

July 30. 2010 15:47

My home we've got tons of getaway owners - So we were hit very hard by the housing down turn

Myrtle Beach Homes

July 31. 2010 00:11

All my fellows order autobiographical essay at the custom research paperservice. Apparently, I would purchase term paper too.

term paper help

Add comment


(Will show your Gravatar icon)