'Accessing a grid control with UIAutomation in .NET 5
We've got a C# GUI application (WPF) that for various reasons uses .NET Core 3.1. In that application we have a custom grid control that we would like to talk to using UIAutomation.
Our test harness application, a console app using .NET 5.0, does this:
- Uses Process.Start() to run our main application.
- Creates an instance of CUIAutomation.
- Passes the handle of the main application's main window to IUIAutomation.ElementFromHandle() to get an IUIAutomationElement object.
- Calls FindAll(TreeScope.TreeScope_Children) recursively to find all the elements. Those elements that have an automation ID are stored in a dictionary.
That all works great. In the test harness, we can load the main application, and then find the element with automation ID "ExitButton" and click on it. Woohoo!
So back in the main application, we have a grid. We assign the grid an automation ID, and when we access that element in the test harness, we can see the grid's OnCreateAutomationPeer() being called. It returns a custom automation peer object (derives from FrameworkElementAutomationPeer, also implements IGridProvider), and our peer object responds to a few basic requests (IsControlElementCore, GetAutomationIdCore) so we know the test harness & peer are talking.
So now the challenge.
How do we get our test harness to do any grid stuff?
From reading online, it seems like we need to call something like
gridElement.GetCurrentPropertyValue(GridPattern.ColumnCountProperty)
but no matter what we try, we cannot find anything named "GridPattern". It doesn't show up in any of the Windows UIAutomation DLLs, nothing in Nuget seems to help.
Where is GridPattern defined? Or are we getting at the grid testing functionality the wrong way?
EDIT #1
By manually editing our test harness' CSPROJ file and adding a reference to Microsoft.WindowsDesktop.App.WPF (as described in this question) the compiler now knows what GridPattern is. However, we're still not sure how to access grid functionality in our test harness.
EDIT #2
The compiler lets us call
GetCurrentPattern(GridPatternIdentifiers.ColumnCountProperty.Id)
in our test harness, but at runtime it throws an exception "Value does not fall within the expected range."
EDIT #3
Calling GetCurrentPropertyValue(GridPatternIdentifiers.ColumnCountProperty.Id) in the test harness works correctly to retrieve the value of the ColumnCount property on the peer object in the main application
EDIT #4
Calling GetCurrentPattern(GridPatternIdentifiers.Pattern.Id) in our test harness doesn't throw an exception, but returns an object of type System.__ComObject which is not obviously useful. Simply casting the __ComObject to a GridPattern throws the expected exception "Cannot convert type 'System.__ComObject' to 'System.Windows.Automation.GridPattern'"
EDIT #5
From looking through the source code, we discovered the GUID of UIAutomationClient.IUIAutomationGridPattern. Passing this to GetCurrentPatternAs(GridPatternIdentifiers.Pattern.Id, gridPatternGUID) works, in that it doesn't fail, but rather returns the IntPtr value 1526502600256.
Only remaining question:
There is a function GridPattern.GetItem() used to retrieve an automation element the represents a specific cell. We still don't know how to get an actual GridPattern object in the test harness.
Solution 1:[1]
Finally found the last piece of the magic incantation:
UIAutomationClient.IUIAutomationGridPattern gridPattern = transmitterGrid.Auto.GetCurrentPattern(GridPatternIdentifiers.Pattern.Id) as UIAutomationClient.IUIAutomationGridPattern;
This gives me a gridPattern object that, when called from the test harness, invokes the matching function in the peer in the main application.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Betty Crokker |
