0

I've simplified this problem as much as I can and the code below can be cut&pasted into a 'test.linq' file and loaded into LinqPad. As it stands running this code in LinqPad will show it working - the intention is to find the pane with AutomationId tabPage1 using the UI Automation framework.

Now comment out the working line and bring in the broken line. Now the tab page cannot be found... the only difference is the tab page is declared with a Text property.

I've found a series of blogs which might indicate that the fault lies with an automation provider that the TabControl has but having decompiled the TabControl source I can't see that this is the case but the base Control implements a handler for WM_GETOBJECT and I'm really not sure where that leads.

Any ideas?

<Query Kind="Statements">
  <Reference>&lt;RuntimeDirectory&gt;\WPF\UIAutomationClient.dll</Reference>
  <Reference>&lt;RuntimeDirectory&gt;\wpf\UIAutomationProvider.dll</Reference>
  <Reference>&lt;RuntimeDirectory&gt;\wpf\UIAutomationTypes.dll</Reference>
  <Reference>&lt;RuntimeDirectory&gt;\Accessibility.dll</Reference>
  <Reference>&lt;RuntimeDirectory&gt;\wpf\WindowsBase.dll</Reference>
  <Reference>&lt;RuntimeDirectory&gt;\System.Windows.Forms.dll</Reference>
  <Reference>&lt;RuntimeDirectory&gt;\System.Security.dll</Reference>
  <Reference>&lt;RuntimeDirectory&gt;\System.Configuration.dll</Reference>
  <Reference>&lt;RuntimeDirectory&gt;\System.Deployment.dll</Reference>
  <Reference>&lt;RuntimeDirectory&gt;\System.Runtime.Serialization.Formatters.Soap.dll</Reference>
  <Namespace>System.Windows.Automation</Namespace>
  <Namespace>System.Windows.Forms</Namespace>
</Query>

var tabControl = new TabControl();
tabControl.Name = "tabControl";

// Broken
//tabControl.TabPages.Add(new TabPage() { Name = "tabPage1", Text = "First Tab" });

// Working
tabControl.TabPages.Add(new TabPage() { Name = "tabPage1" });

var form = new Form() { Name = "Form1" };
form.Controls.Add(tabControl);
form.Show();

var desktop = AutomationElement.RootElement;
var frmTest = desktop.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "Form1"));
var tabPage1 = frmTest.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "tabPage1"));
tabPage1.Dump("tabPage1");
Phil
  • 2,232
  • 1
  • 26
  • 35
  • UIAutomation can be a lot like herding cats. But yes, TabPage has the ControlStyles.UseTextForAccessibility style turned on so setting its Text property also sets its accessibility id. It is unclear how far you want to push this by setting the TabControl's AccessibleObject property. – Hans Passant Jan 23 '15 at 15:14
  • Thanks Hans, I'm not sure how I would have come across that without you pointing it out! The TabControl I'm trying to automate is actually my own owner drawn SubClass of Microsofts TabControl so I'll have a play and see if I can't turn the UseTextForAccessibility control style off. I'm between projects at the moment but in a few days I'll come back with my findings. – Phil Jan 30 '15 at 09:32
  • I have now had chance to update my source above and subclassed both `TabControl` and `TabPage` calling `SetStyle(ControlStyles.UseTextForAccessibility, false); UpdateStyles();` in both constructors but I'm still not having any luck! Looking at [Microsofts reference source](http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Control.cs,488) suggests that `UseTextForAccessibility` is set for all controls so I'm wondering whether this is really the answer since otherwise I'd would have seen this problem more? – Phil Feb 03 '15 at 09:03

0 Answers0