Search code examples
wpfxamldata-bindingdatatemplate

Binding to DataTemplate within DataGrid


I'm trying to work with a DataGrid in XAML that is bound to an ObservableCollection. I've had no trouble getting simple text to display using DataGridTextColumns that are bound to individual columns of each item in the ObservableCollection, but I want to get images displaying in the grid, too. As such, I've started working with a DataGridTemplateColumn, but I can't seem to get the binding logic correct. I've simplified it down to just trying to get text to display using it before I move on to putting an image in.

Below is a simplified version of my code:

<DataGrid x:Name="DataGrid" Width="Auto" MinWidth="600" AutoGenerateColumns="False"
            SelectionMode="Single"
            ItemsSource="{Binding Collection, Mode=OneWay}" CanUserReorderColumns="True" CanUserSortColumns="True">
    <DataGrid.Columns>
        <DataGridTextColumn x:Name="ID" Header="ID" Binding="{Binding ID, Mode=OneWay}"/>
        <DataGridTemplateColumn x:Name="Number" Header="Number">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding DataContext.Number}" DataContext="{Binding Collection, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

When I use this specifically, I get numerous errors like the one below:

System.Windows.Data Error: 40 : BindingExpression path error: 'Collection' property not found on 'object' ''DataGrid' (Name='DataGrid')'. BindingExpression:Path=Collection; DataItem='DataGrid' (Name='DataGrid'); target element is 'TextBlock' (Name=''); target property is 'DataContext' (type 'Object')

I've tried adjusting this in every way I can think of - changing the syntax of my text binding or the DataContext binding in all kinds of different ways - but I just keep getting errors like the above or it will simply display as blank without showing any text. Another method I tried that didn't work, for example:

<TextBlock Text="{Binding Number}" DataContext="{Binding DataContext.Collection, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>

I just want to figure out how to display something as simple as text in the grid so I can move on to using that logic for other things. I can't seem to find any information that solves my specific issue.

I'm sure its something simple I'm just not understanding about the logic in XAML, so any advice or suggestions would be appreciated.


Solution

  • The TextBlock DataContext will already be set to the item in the collection, so you can simply bind directly to a property of the item.

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