I have a simple Microsoft WPF application that consists of a (data driven) GroupBox containing a Group of Cats and a group of Dogs. Both the Cat and Dog groups contain two group items each. When I run the application all appears fine, I can see the groups and their content on the screen.
Running the application produces the following window:
However, when I create a UIAutomation test I can’t find any AutomationElements for the group items, just the groups; only the Cat and Dog Groups can be accessed using either the AutomationElement route, or seen in UISpy.exe as per the image below:
The child components for the individual Cat and Dog group items are not present and I need to be able to retrieve them as AutomationElements in my test code:
[TestMethod]
public void MyTest()
{
Condition controlTypeCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Group);
var foreGroundWindow = GetForegroundWindow();
var collection = foreGroundWindow.FindAll(TreeScope.Descendants, controlTypeCondition);
foreach (AutomationElement element in collection)
{
logger.Debug("Name: " + element.Current.Name);
var children = element.FindAll(TreeScope.Children, Condition.TrueCondition);
logger.Debug("Number of children: " + children.Count);
}
}
The above currently outputs:
Name: Cat
Number of children: 0
Name: Dog
Number of children: 0
To reproduce this issue, create a new WPF application in Visual Studio (called WpfApplication1) and replace the contents of the MainWindow.xaml with the following:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
</ResourceDictionary.MergedDictionaries>
<XmlDataProvider x:Key="data">
<x:XData>
<Animals xmlns="">
<Animal name="Felix" Species="Cat" />
<Animal name="Garfield" Species="Cat" />
<Animal name="Rex" Species="Dog" />
<Animal name="Rover" Species="Dog" />
</Animals>
</x:XData>
</XmlDataProvider>
<CollectionViewSource x:Key="AnimalsBySpecies" Source="{Binding Source={StaticResource data}, XPath=Animals/Animal}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="@Species" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</ResourceDictionary>
</Window.Resources>
<ItemsControl ItemsSource="{Binding Source={StaticResource AnimalsBySpecies}}">
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<GroupBox Header="{Binding Name}">
<ItemsPresenter />
</GroupBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ItemsControl.GroupStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=@name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
In reality my code doesn't look exactly like this as it is an MVVM application. But for brevity I have simplified that down into a single XAML file which reproduces the same issue. The key point to note is that the group contents are populated from a XAML Binding.
So how can I get to the content using UIAutomation?
Any help greatly appreciated!
Try using the the native-code UI Automation API, instead of the managed API that's part of the .Net framework. This newer API supports additional accessibility, and is recommended by Microsoft. Here's some more information, be sure to read the links in the original post.
In addition, UISpy is deprecated and no longer recommended. Instead, use UIA Verify tool which, in addition to being much more stable and faster than UISpy, also works with the Windows Automation API described above and thus may expose more information about the controls you're interested at.