views:

46

answers:

1

Summary

In my WPF application, I needed a TabControl with buttons on the left, so I defined a ControlTemplate with the layout I wanted and it worked fine.

However, my tester's automated testing tool can't see any of the content of the tabs, including the currently selected tab.

Question: How can I keep my TabControl testable by the automated testing tools, while still defining the ControlTemplate?


Details

I'm developing a WPF application using WPF 3.5
My tester is using an automated test tool called QTP
He says he can test anything you can see with UISpy.exe

  • When I use a straight TabControl with no Template applied, UISpy can see the content of the currently selected tab.
  • However, when I use a ContentTemplate to change the layout (code shown below), UISpy can still see the tab headers... but it cannot see the content.

Sample WPF application (Xaml):

<Window x:Class="TabControlTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Tab Control Test"
        Height="300"
        Width="300">
    <Window.Resources>
        <ControlTemplate x:Key="ButtonsOnLeftTabLayout"
                         TargetType="{x:Type TabControl}">
            <DockPanel>
                <StackPanel DockPanel.Dock="Left"
                            IsItemsHost="True" />
                <ContentPresenter Content="{TemplateBinding SelectedContent}" />
            </DockPanel>
        </ControlTemplate>
    </Window.Resources>
    <TabControl Template="{StaticResource ButtonsOnLeftTabLayout}">
        <TabItem Header="Tab 1">
            <StackPanel>
                <Button HorizontalAlignment="Center">Button 1</Button>
            </StackPanel>
        </TabItem>
        <TabItem Header="Tab 2">
            <StackPanel>
                <Button HorizontalAlignment="Center">Button 2</Button>
            </StackPanel>
        </TabItem>
    </TabControl>
</Window>

What my search has found so far:

  • A bunch of stuff about having to write a custom TabControl with a custom AutomationPeer (e.g. MSFT answer to forum question UI Automation: accessing control in a ControlTemplate, blog posting Custom Controls and UI Automation). But my every instinct says that's crazy overkill, "there must be a simpler way!"
  • Some suggestions about giving the ContentPresenter a Name, or x:Name, or AutomationProperties.AutomationId -- none of which have any effect

(After search I finally found answer but it took longer than I thought it should have, and the AutomationPeer early findings were indeed incorrect, so I'm writing this as a SO question and self-answer, in case it helps anyone else in future)

+4  A: 

Found answer in a different MSFT response on a different but similar msdn forum question, TabControl controls are missing for UI Automation.

To get the UI Automation working for ContentTemplated TabControl, add Name="PART_SelectedContentHost" attribute to the ContentPresenter, like this

<ContentPresenter Name="PART_SelectedContentHost"
                  Content="{TemplateBinding SelectedContent}"/>

That's all it takes. UISpy can now see the content of the currently selected tab.

Daryn