Both WinForms and WPF controls in DotNetBrowser provide UI Automation support if they are running in the heavyweight rendering mode. The --force-renderer-accessibility
Chromium switch should be specified to force enable Chromium accessibility features.
MainWindow.xaml
<Window x:Class="UIAutomationSample.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" xmlns:wpf="clr-namespace:DotNetBrowser.WPF;assembly=DotNetBrowser" mc:Ignorable="d" Title="MainWindow" Height="600" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="199*"/> <RowDefinition Height="88*"/> <RowDefinition Height="29"/> </Grid.RowDefinitions> <wpf:WPFBrowserView Grid.Row="0" URL="teamdev.com/dotnetbrowser" /> <TextBox Name="TextOutput" Grid.Row="1" VerticalScrollBarVisibility="Auto" /> <Button Grid.Row="2" Name="Button" Content="Access DotNetBrowser contents via UI Automation" Click="Button_Click"> </Button> </Grid> </Window>
C#
MainWindow.xaml.cs
using System; using System.Diagnostics; using System.Windows; using DotNetBrowser; using System.Windows.Automation; using Condition = System.Windows.Automation.Condition; namespace UIAutomationSample { public partial class MainWindow : Window { public MainWindow() { BrowserPreferences.SetChromiumSwitches("--force-renderer-accessibility"); InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { TextOutput.Clear(); Process currentProcess = Process.GetCurrentProcess(); AutomationElement chromiumElement = GetChromiumElement(currentProcess); if (chromiumElement != null) { Log("-- Element Properties --"); AutomationProperty[] properties = chromiumElement.GetSupportedProperties(); foreach (AutomationProperty prop in properties) { Log("ProgrammaticName: " + prop.ProgrammaticName); Log("\tProperty Name: " + Automation.PropertyName(prop)); var currentPropertyValue = chromiumElement.GetCurrentPropertyValue(prop); Log("\tProperty Value: " + currentPropertyValue); } Log("-- Element Patterns --"); AutomationPattern[] patterns = chromiumElement.GetSupportedPatterns(); foreach (AutomationPattern pattern in patterns) { Log("ProgrammaticName: " + pattern.ProgrammaticName); Log("\tPattern Name: " + Automation.PatternName(pattern)); var currentPattern = chromiumElement.GetCurrentPattern(pattern); Log("\tPattern Value: " + currentPattern); if (currentPattern is ValuePattern) { ValuePattern valuePattern = currentPattern as ValuePattern; string value = valuePattern.Current.Value; Log("\tValuePattern Value: " + value); } } var children = chromiumElement.FindAll( TreeScope.Descendants, Condition.TrueCondition); Log("-- Element Children --"); Log("Children count: "+children.Count); Log("-- End --"); } else { Log("-- Chromium automation element not found --"); } } private static AutomationElement GetChromiumElement(Process process) { AutomationElement element = null; if (process != null && process.MainWindowHandle != IntPtr.Zero) { AutomationElement rootElement = AutomationElement.FromHandle(process.MainWindowHandle); if (rootElement == null) return null; System.Windows.Automation.Condition conditions = new AndCondition( new PropertyCondition( AutomationElement.ClassNameProperty, "Chrome_RenderWidgetHostHWND"), new PropertyCondition( AutomationElement.ControlTypeProperty, ControlType.Document) ); element = rootElement.FindFirst( TreeScope.Descendants, conditions); } return element; } private void Log(string text) { Dispatcher.BeginInvoke( (Action)( () => TextOutput.AppendText(text + Environment.NewLine)) ); } } }
VB.NET
MainWindow.xaml.vb
Imports DotNetBrowser Imports System.Windows.Automation Imports Condition = System.Windows.Automation.Condition Namespace UIAutomationSample Public Partial Class MainWindow Inherits Window Public Sub New() BrowserPreferences.SetChromiumSwitches("--force-renderer-accessibility") InitializeComponent() End Sub Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) TextOutput.Clear() Dim currentProcess As Process = Process.GetCurrentProcess() Dim chromiumElement As AutomationElement = GetChromiumElement(currentProcess) If chromiumElement IsNot Nothing Then Log("-- Element Properties --") Dim properties As AutomationProperty() = chromiumElement.GetSupportedProperties() For Each prop As AutomationProperty In properties Log("ProgrammaticName: " & prop.ProgrammaticName) Log(vbTab & "Property Name: " & Automation.PropertyName(prop)) Dim currentPropertyValue = chromiumElement.GetCurrentPropertyValue(prop) If currentPropertyValue IsNot Nothing Then Log(vbTab & "Property Value: " & currentPropertyValue.ToString()) End If Next Log("-- Element Patterns --") Dim patterns As AutomationPattern() = chromiumElement.GetSupportedPatterns() For Each pattern As AutomationPattern In patterns Log("ProgrammaticName: " & pattern.ProgrammaticName) Log(vbTab & "Pattern Name: " & Automation.PatternName(pattern)) Dim currentPattern = chromiumElement.GetCurrentPattern(pattern) Log(vbTab & "Pattern Value: " & currentPattern.ToString()) If TypeOf currentPattern Is ValuePattern Then Dim valuePattern As ValuePattern = TryCast(currentPattern, ValuePattern) Dim value As String = valuePattern.Current.Value Log(vbTab & "ValuePattern Value: " & value) End If Next Dim children = chromiumElement.FindAll(TreeScope.Descendants, Condition.TrueCondition) Log("-- Element Children --") Log("Children count: " & children.Count) Log("-- End --") Else Log("-- Chromium automation element not found --") End If End Sub Private Shared Function GetChromiumElement(ByVal process As Process) As AutomationElement Dim element As AutomationElement = Nothing If process IsNot Nothing AndAlso process.MainWindowHandle <> IntPtr.Zero Then Dim rootElement As AutomationElement = AutomationElement.FromHandle(process.MainWindowHandle) If rootElement Is Nothing Then Return Nothing Dim conditions As System.Windows.Automation.Condition = New AndCondition( New PropertyCondition(AutomationElement.ClassNameProperty, "Chrome_RenderWidgetHostHWND"), New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document)) element = rootElement.FindFirst(TreeScope.Descendants, conditions) End If Return element End Function Private Sub Log(ByVal text As String) Dispatcher.BeginInvoke(CType((Sub() TextOutput.AppendText(text & Environment.NewLine)), Action)) End Sub End Class End Namespace