Using DataGridAutomation peer - exposing DataGridCellItemAutomationPeer.OwningCell

Nov 21, 2008 at 11:17 AM

I'm successfully using the automation peers to assist with my unit testing, whilst doing this I was able to get down to the DataGridCellItem but couldn't see a way of actually getting the datagridcell. For example I wanted to find a cell put it into edit mode then extract the textbox and set the value then commit the edit and check that the class behind the datatable was actully updated. I couldn't see any way of doing this so I had to make the OwningCell property public? I was wondering whether anything could be done with the TextBlockAutomationPeer?

Please advise on alternatives my example code is below.


Dim lobjDataGridPeer As DataGridAutomationPeer = Nothing
Dim lobjScrollPeer As ScrollViewerAutomationPeer = Nothing

Dim lobjWindowPeer As WindowAutomationPeer = New WindowAutomationPeer(lobjFilterGrid)
Dim lobjWinChildren As List(Of AutomationPeer) = lobjWindowPeer.GetChildren()
For Each lobjAutomationPeer As AutomationPeer In lobjWinChildren
If TypeOf lobjAutomationPeer Is DataGridAutomationPeer Then
    lobjDataGridPeer = DirectCast(lobjAutomationPeer, DataGridAutomationPeer)
End If
Assert.IsNotNull(lobjDataGridPeer, "DataGrid Automation peer is nothing")
' Find me the row
' Walk around the children looking for the ScollingViewer this is the first child
Dim lobjScrollPeer As ScrollViewerAutomationPeer = Nothing
For Each lobjAutomationPeer As AutomationPeer In lobjDataGridPeer.GetChildren
If TypeOf lobjAutomationPeer Is ScrollViewerAutomationPeer Then
    lobjScrollPeer = DirectCast(lobjAutomationPeer, ScrollViewerAutomationPeer)
End If
' Walk around the children of the scrolling viewer looking for the DataGridRowsPresenter
Dim lobjColHdrButton As ButtonAutomationPeer = Nothing
Dim lobjColHdrs As DataGridColumnHeadersPresenterAutomationPeer = Nothing
Dim lobjGridRows As DataGridRowsPresenterAutomationPeer = Nothing
For Each lobjAutomationPeer As AutomationPeer In lobjScrollPeer.GetChildren
If TypeOf lobjAutomationPeer Is ButtonAutomationPeer Then
    lobjColHdrButton = DirectCast(lobjAutomationPeer, ButtonAutomationPeer)
ElseIf TypeOf lobjAutomationPeer Is DataGridColumnHeadersPresenterAutomationPeer Then
    lobjColHdrs = DirectCast(lobjAutomationPeer, DataGridColumnHeadersPresenterAutomationPeer)
ElseIf TypeOf lobjAutomationPeer Is DataGridRowsPresenterAutomationPeer Then
    lobjGridRows = DirectCast(lobjAutomationPeer, DataGridRowsPresenterAutomationPeer)
End If
' Walk around the DataGridRowsPresenter picking the row specified out otherwise just return the last one
lintRow = 0
Dim lintRowCnt As Integer = 0
Dim lobjDataGridItem As DataGridItemAutomationPeer = Nothing
For Each lobjAutomationPeer As AutomationPeer In lobjGridRows.GetChildren
If TypeOf lobjAutomationPeer Is DataGridItemAutomationPeer Then
    lobjDataGridItem = DirectCast(lobjAutomationPeer, DataGridItemAutomationPeer)
    If lintRowCnt = lintRow Then Exit For
    lintRowCnt += 1
End If
Assert.IsNotNull(lobjDataGridItem, "lobjDataGridItem Automation peer is nothing for row " & lintRow)
' Find me the cell in the 2nd Column
' Walk around the Row looking for the column specified
lintColumn = 1
Dim lintCnt As Integer = 0
Dim lobjDataGridRowHdr As DataGridRowHeaderAutomationPeer = Nothing
Dim lobjDataGridCellItem As DataGridCellItemAutomationPeer = Nothing
Dim lobjDataGridDetailsPresenter As DataGridDetailsPresenterAutomationPeer = Nothing
For Each lobjAutomationPeer As AutomationPeer In lobjDataGridItem.GetChildren
If TypeOf lobjAutomationPeer Is DataGridRowHeaderAutomationPeer Then
    lobjDataGridRowHdr = DirectCast(lobjAutomationPeer, DataGridRowHeaderAutomationPeer)
ElseIf TypeOf lobjAutomationPeer Is DataGridCellItemAutomationPeer Then
    lobjDataGridCellItem = DirectCast(lobjAutomationPeer, DataGridCellItemAutomationPeer)
    If lintCnt = lintColumn Then Exit For
    lintCnt += 1
ElseIf TypeOf lobjAutomationPeer Is DataGridDetailsPresenterAutomationPeer Then
    lobjDataGridDetailsPresenter = DirectCast(lobjAutomationPeer, DataGridDetailsPresenterAutomationPeer)
End If
Assert.IsNotNull(lobjDataGridCellItem, "DataGridCellItemAutomationPeer Automation peer is nothing for column " & lintColumn)
' Look at DataGridCellItem peer
'   Children are the editable items behind the cell in this case CheckBox
Dim lobjTextBlock As TextBlockAutomationPeer = Nothing
For Each lobjAutomationPeer As AutomationPeer In lobjDataGridCellItem.GetChildren
If TypeOf lobjAutomationPeer Is TextBlockAutomationPeer Then
    lobjTextBlock = DirectCast(lobjAutomationPeer, TextBlockAutomationPeer)
End If
Assert.IsNotNull(lobjTextBlock, "Can't find the correct cell expecting a Textblock")

Dim lblnSelected As Boolean = DirectCast(lobjDataGridCellItem, ISelectionItemProvider).IsSelected
If lblnSelected = False Then
    DirectCast(lobjDataGridCellItem, ISelectionItemProvider).Select()
End If

Console.WriteLine("UpdateTextBoxCell:- Calling Invoke which should put cell into Edit mode")
DirectCast(lobjDataGridCellItem, IInvokeProvider).Invoke()
' Set the text
Dim lobjDataGridCell As DataGridCell = TryCast(lobjDataGridCellItem.OwningCell, DataGridCell)
Assert.IsNotNull(lobjDataGridCell, "UpdateTextBoxCell:- Can't get the datagrid cell to set the value")

Assert.IsInstanceOfType(lobjDataGridCell.Content, GetType(TextBox), "GridCell.Content not of the expected type (textbox) actual type (" & lobjDataGridCell.Content.ToString & ")")
If TypeOf lobjDataGridCell.Content Is TextBox Then
    Dim lobjEditingElement As TextBox = TryCast(lobjDataGridCell.Content, TextBox)
    If lobjEditingElement IsNot Nothing Then
    Console.WriteLine("UpdateTextBoxCell:- Got textbox setting it to a value")
    lobjEditingElement.Text = lstrNewValue
    End If
End If
Console.WriteLine("UpdateTextBoxCell:- Calling Invoke which should commit cell")
DirectCast(lobjDataGridCellItem, IInvokeProvider).Invoke()

Nov 21, 2008 at 5:28 PM
Hi amitchel7,

The purpose of automation peers is never to expose the actual object itself. The reason being automation peers might be used from processes different from the object's process like from Screen Readers in which case you wont have access to the actual object. In fact if we are in the same process why do we need an automation peer, we can directly access the object itself.

Anways should provide more insight about automation itself.