Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XAML - Binding row and column index of cell to automation ID

Tags:

xaml

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.

like image 380
CSD Avatar asked Jan 26 '12 15:01

CSD


People also ask

How to bind to an index in XAML?

A binding within a binding is not possible, So in XAML you can't bind to "index". a. Chris Moser's method, You can create a DependencyProperty that binds to "index" Specify a change listener on the RegisterAttached handler and do your work there.

How to bind to the current location in XAML?

One simple option would be to just expose a CurrentLocation property within your ViewModel, which was effectively Location [index]. You could then bind to it directly. Show activity on this post. A binding within a binding is not possible, So in XAML you can't bind to "index". a.

How to associate the Index in my XAML with the ViewModel?

where index is an integer in my viewmodel, does not work. Does anyone know how I can associate the index in my xaml with the property in my viewmodel? One simple option would be to just expose a CurrentLocation property within your ViewModel, which was effectively Location [index].

How do I insert a tag in a cell binding table?

Insert Tag - Inserts a Tag reference into the Value cell of the selected row. Each row in the Cell Bindings table needs three values to work properly: a Row identifier which is used to figure out which row the cell binding is on, a Column identifier to determine the column of the cell, and a Value which will replace the original value of the cell.


1 Answers

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>
like image 170
CSD Avatar answered Oct 04 '22 22:10

CSD