I have a DataGrid where the ItemsSource is bound to an ObservableCollection
<DataGrid ItemsSource="{Binding Items}">
Each item in the ObservableCollection also has an ObservableCollection of strings.
One of the columns is a DataGridTemplateColumn that contains a ComboBox. I would like each row's ComboBox to contain items in the ObservableCollection of strings in that row's ViewModel. If I bind it normally, this works. However, I can't seem to get it to work if I am using a CompositeCollection.
<DataGridTemplateColumn Header="Column Title">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedValue="{Binding Selected, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding ???}" />
<ComboBoxItem>
<TextBlock>
<Hyperlink Command="{Binding DataContext.EditList, Source={x:Reference myGridName}}">Edit List</Hyperlink>
</TextBlock>
</ComboBoxItem>
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
I'm not sure what to use for the Binding to get it to work. Without the CompositeCollection, I can simply do:
<ComboBox ItemsSource="{Binding SubItems}">
In searching, I know you need to set a source for the CollectionContainer, but most examples were for setting it to a static list that's the same for all rows. I need each row to bind to the ObservableCollection in that row's ViewModel.
I've tried:
<CollectionContainer Collection="{Binding DataContext.SubItems, RelativeSource={RelativeSource AncestorType=ComboBox}}" />
But that results in an error of:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ComboBox', AncestorLevel='1'' ...
You can use the following DataTemplate:
<DataTemplate>
<ComboBox x:Name="cb"
SelectedValue="{Binding Selected, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.Resources>
<DiscreteObjectKeyFrame x:Key="proxy" Value="{Binding ElementName=cb}"/>
</ComboBox.Resources>
<ComboBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Value.DataContext.SubItems, Source={StaticResource proxy}}" />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
</DataTemplate>
x:Refefrence
comes from this explanation. However, this answer is not enough. In fact, you need a proxy as explained in this answer.
Hope it helps.