R – WPF UI automation – Doesn’t support rows? (or how can I select and deselect an entire row)

.net-3.5datagridui-automationwpf

Note: This is no longer an issue, the .NET 4 built-in DataGrid solves this problem


I have a WPF app which is using a DataGrid; I'm using the WPF ui automation API to write some automated tests for it.
The DataGrid is the WPFToolkit one, I'm using the .NET 3.5SP1 with VS2008, and, the datagrid has multi-select enabled.

Where I'm at is that from my test can find the datagrid, and I can find individual cells within the grid using the GridPattern.GetItem method, and select them by setting SelectionItemPattern.Select. Method

The code looks somewhat like this:

AutomationElement mainGrid = // find the grid in the window
var columnCount = (int)mainGrid.GetCurrentPropertyValue(GridPattern.ColumnCountProperty);
var mainGridPattern = (GridPattern)mainGrid.GetCurrentPattern(GridPattern.Pattern);

var rowToSelect = 2;

// select just the first cell
var item = mainGridPattern.GetItem(rowToSelect, 0);
var itemPattern = (SelectionItemPattern)item.GetCurrentPattern(SelectionItemPattern.Pattern);
itemPattern.Select();

This seems to work, but it only selects the first individual cell, not the entire table row (which has 10 columns) but I can't work out how to deselect an item. The only thing I can find that looks like it might work is to call SelectionItemPattern.AddToSelection() on the itemPattern, or the corresponding RemoveFromSelection but when I do either of these, the following exception is raised:

=> Cannot change cell selection when the SelectionUnit is FullRow.
   at MS.Internal.Automation.ElementUtil.Invoke(AutomationPeer peer, DispatcherOperationCallback work, Object arg)
   at MS.Internal.Automation.SelectionItemProviderWrapper.AddToSelection()

The underlying root issue appears to be that (as far as I can see) the WPF UI automation API has no concept of a grid Row, only cells. This seems somewhat problematic – Is this right?

Sidenote: I had previously been using the White UI automation framework – this doesn't use UI automation to select grid rows, instead it moves the mouse to the row location and clicks it – which caused random failures of our tests – is this why they're using the mouse to do the selection though?

Best Answer

If you use UISpy to look at the structure of your DataGrid as UIAutomation sees it, you'll notice that the DataGrid element contains a RowsPresenter, and the RowsPresenter contains a number of DataGridRows, each containing a DataGridCell.

I suspect what's happening is that var item = mainGridPattern.GetItem(rowToSelect, 0); is returning the item representing the cell, whereas you want the item representing the whole row.

You can get this by calling item.CachedParent - then Select() that.

Related Topic