C# – How to bind to DataGridRow item from templated cell within that row in xaml

cwpfxaml

What binding is used to bind an element defined in the cell template of a DataGridTemplateColumn to the bound data item of that cell's DataGridRow?

For example, assume the DataGrid Items are objects that have a Name property. What binding is required in the code below to bind the TextBlock Text to the "Name" property of the data item represented by the parent row?

(And yes, in the example I could just use DataGridTextColumn, but I'm just simplifying for example sake.)

<DataGrid ItemsSource="{Binding Items}">
  <DataGrid.Columns>
    <DataGridTemplateColumn Header="Name">
      <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding ???}"/>
        </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
  </DataGrid.Columns>
</DataGrid>

Best Answer

You don't need any special kind of binding - the TextBlock inherits the datacontext from the row (which is set to the bound item).

So you can just do this:

<TextBlock Text="{Binding Name}" />

To see that the datacontext is actually inherited by the TextBlock, you can set a different datacontext which is closer to the TextBlock in the control hierarchy. The TextBlock will now use that datacontext instead.

In this example the name of the StackPanel will be shown in the TextBlock instead of the name on the bound row object on the DataGrid:

<DataTemplate>
    <StackPanel x:Name="panel1" DataContext="{Binding RelativeSource={RelativeSource Self}}">

        <!-- Binds to Name on the Stackpanel -->
        <TextBlock Text="{Binding Name}" />

        <!-- Binds to Name on object bound to DataGridRow -->
        <TextBlock Text="{Binding DataContext.Name, 
                         RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}}" />

    </StackPanel>
</DataTemplate>
Related Topic