My goal was to lay out a data grid that allowed you to change the units on each row. Each row represented a different quantity, so the available units to choose from weren’t necessarily the same.

My view model looked something like this:

public class MyAwesomeViewModel : ViewModelBase {
    public IEnumerable<Unit> Units {get;set;}
    public string SelectedUnit {get;set;}
    ...
}

And then my XAML looked something like this:

<DataGrid ...>
    <DataGrid.Columns>
        <DataGridComboBoxColumn
            SelectedValueBinding="{Binding Path=SelectedUnit, Mode=TwoWay}"
            ItemsSource="{Binding Path=Units}"/>
    ...

This raised an error at runtime, claiming:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or
FrameworkContentElement for target element. BindingExpression:Path=Units;
DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=18876224);
target property is 'ItemsSource' (type 'IEnumerable')

And the binding failed, with nothing in the combo box.

Why did this happen? From what I can tell, the problem is that WPF defines the columns first before populating the data grid. As such, the binding scope is different - it can’t be per-row, which is what we need.

Since the Units property isn’t available at the scope it’s operating in (presumably the DataGridComboBoxColumn has no DataContext), the binding fails. You could presumably set it to a StaticResource or some other static item using x:Static, but that wouldn’t work for my case, since the available units depended on the row.

The solution I ended up going with was a DataGridTemplateColumn, since that would allow me to change the contents depending on the row.

<DataGridTemplateColumn Header="Unit">
    <DataGridTemplateColumn.CellTemplate>
        <HierarchicalDataTemplate>
            <ComboBox ItemsSource="{Binding Path=Units}"
                        SelectedValue="{Binding Path=SelectedUnit, Mode=TwoWay}"/>
        </HierarchicalDataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>