6

I'm in the process of giving automation IDs to individual cells within a WPF datagrid, but I've hit a bit of a snag. I've decided to try naming the cells according to their position in the grid (row index and column index). Using a UI inspector and highlighting one of the DataGridCells in question shows the following properties:

GridItem.Row: 2 GridItem.Column: 0

... which leads me to believe that I can access these properties via binding. However, I've spent the better part of the last few days combing the Internet for how to go about this, but haven't found anything.

The current XAML code is as follows (the '???' are placeholders):

<DataGrid.CellStyle>
  <Style TargetType="{x:Type DataGridCell}">
    <Setter Property="AutomationProperties.AutomationId">
      <Setter.Value>
        <MultiBinding StringFormat="cell:{0}-{1}">
          <Binding ??? />
          <Binding ??? />
        </MultiBinding>
      </Setter.Value>
    </Setter> 
  </Style>
</DataGrid.CellStyle>

Does such a path to these properties exist? Or does another method exist for giving unique automation IDs to individual cells? I'm not very experienced with WPF and XAML so any pointers are appreciated.

Thanks in advance.

CSD
  • 171
  • 2
  • 8
  • I don't sure, but try – Eyjafjallajokull Jan 26 '12 at 19:42
  • Tried inserting your snippet but it did not produce the correct result unfortunately (the automationId is blank for whatever reason). Thank you for responding - I'll keep playing around with things and post if I stumble upon something. – CSD Jan 26 '12 at 20:28

2 Answers2

8

Got it to work finally. Posting solution here so that others may benefit.

The code behind (based off http://gregandora.wordpress.com/2011/01/11/wpf-4-datagrid-getting-the-row-number-into-the-rowheader/):

Private Sub DataGrid_LoadingRow(sender As System.Object, e As System.Windows.Controls.DataGridRowEventArgs)
  e.Row.Tag = (e.Row.GetIndex()).ToString()
End Sub

And the XAML:

<DataGrid ... LoadingRow="DataGrid_LoadingRow" >

<DataGrid.ItemContainerStyle>
  <Style TargetType="{x:Type DataGridRow}">
    <Setter Property="AutomationProperties.AutomationId">
      <Setter.Value>
        <MultiBinding StringFormat="Row{0}">
          <Binding Path="(DataGridRow.Tag)"
                   RelativeSource="{RelativeSource Mode=Self}" />
        </MultiBinding>
      </Setter.Value>
    </Setter>
    <Setter Property="AutomationProperties.Name">
      <Setter.Value>
        <MultiBinding StringFormat="Row{0}">
          <Binding Path="(DataGridRow.Tag)"
                   RelativeSource="{RelativeSource Mode=Self}" />
        </MultiBinding>
      </Setter.Value>
    </Setter>
  </Style>
</DataGrid.ItemContainerStyle>

...

<DataGrid.CellStyle>
  <Style>
    <Setter Property="AutomationProperties.AutomationId">
      <Setter.Value>
        <MultiBinding StringFormat="cell{0}Col{1}">

          <!-- bind to row automation name (which contains row index) -->
          <Binding Path="(AutomationProperties.Name)"
                   RelativeSource="{RelativeSource AncestorType=DataGridRow}" />

          <!-- bind to column index -->
          <Binding Path="(DataGridCell.TabIndex)"
                   RelativeSource="{RelativeSource Mode=Self}" />

        </MultiBinding>
      </Setter.Value>
    </Setter> 
  </Style>
</DataGrid.CellStyle>

...

</DataGrid>
g t
  • 7,287
  • 7
  • 50
  • 85
CSD
  • 171
  • 2
  • 8
2

Ok, I've checked it (not with datagrid but with grid, it should be same), and it works:

<AutomationProperties.AutomationId>
    <MultiBinding StringFormat="{}{0} - {1}">
             <Binding Path="(Grid.Row)" RelativeSource="{RelativeSource Mode=Self}" />
             <Binding Path="(Grid.Column)" RelativeSource="{RelativeSource Mode=Self}" />
        </MultiBinding>
</AutomationProperties.AutomationId>
  • 1
    I am now getting "0-0" as the automation ID for all cells in the grid. That's a big step forward compared to what I had before though - thanks for your help! – CSD Jan 27 '12 at 14:55
  • Looked through some other properties of DataGrid and Grid classes... Tried `` but received -1 for all cells. – CSD Jan 27 '12 at 15:06
  • Can you please tell me where are your properties "GridItem.Row" and "GridItem.Column" come? I've created test project with datagrid to inspect this issue using Snoop, but I see no these properties. – Eyjafjallajokull Jan 27 '12 at 19:14
  • I succeed to find the index of column ( ), but I didn't find the row index. – Eyjafjallajokull Jan 27 '12 at 19:16
  • I was using Active Accessibility Object Inspector (INSPECT), but have downloaded Snoop as it looks like it's more up-to-date. I tried to find these properties as well but did not turn up anything. I'm starting to think that GridItem.Row and GridItem.Column may just be extra information displayed in INSPECT (I looked at the MSDN documentation for DataGridCell and DataGrid and neither of these classes have any GridItem properties). – CSD Jan 27 '12 at 19:58
  • Tried binding to Column.DisplayIndex and received an exception, but I did find the column index using '' - at least I'm half-done now, haha. Really liking Snoop so far. – CSD Jan 27 '12 at 20:11