I have a DataGrid with several columns including a DataGridComboBoxColumn.
I'd like the ComboBox to offer a limited selection for the first row only.
<DataGridComboBoxColumn x:Name="myDataGrid"
SelectedItemBinding="{Binding Direction,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={StaticResource DirectionTypesCVS}}"
Header="Direction"
Width="*"/>
My DirectionTypeCVS is a CollectionViewSource that returns a list of DirectionType enums, "NORTH, EAST, SOUTH, WEST". For the first row, I would like to restrict this to "NORTH" and "SOUTH".
I've tried changed the ItemsSource in the code-behind but this doesn't behave correctly. I've also tried adding a CollectionViewSource filter it doesn't appear to be being applied correctly.
What is the correct approach for this?
CodePudding user response:
I would offer you to use DataGridTemplateColumn
instead of DataGridComboBoxColumn
, so you get binding for the row and can find out an AlternationIndex
. What you will need to do is to write a converter.
<DataGrid ItemsSource="..." AutoGenerateColumns="False" AlternationCount="2147483647">
<DataGrid.Columns>
<DataGridTemplateColumn >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding Direction, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource multivalcnv}">
<Binding Source="{StaticResource yourStr}"/>
<Binding Path="AlternationIndex" RelativeSource="{RelativeSource AncestorType=DataGridRow}"/>
</MultiBinding>
</ComboBox.ItemsSource>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
public class MultValConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if(values != null && values.Length == 2 && values[1] is int)
if((int)(values[1]) == 0)
{
return new List<string> { "Do filter the values[0]" };
}
else
return values[0];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException("It's a one way converter.");
}
}
CodePudding user response:
You can get away from using a converter if you set the AlternationCount
property of the DataGrid
to int.MaxValue
and use a Style
with a DataTrigger
that binds to the ItemsControl.AlternationIndex
attached property of the parent DataGridRow
:
<DataGrid ... AlternationCount="2147483647">
<DataGrid.Columns>
<DataGridComboBoxColumn x:Name="myDataGrid"
SelectedItemBinding="{Binding Direction,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Header="Direction"
Width="*">
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Style.Triggers>
<DataTrigger Binding="{Binding (ItemsControl.AlternationIndex),
RelativeSource={RelativeSource AncestorType=DataGridRow}}"
Value="0">
<Setter Property="ItemsSource" Value="{Binding Source={StaticResource DirectionTypesCVSSpecial}}"/>
</DataTrigger>
</Style.Triggers>
<Setter Property="ItemsSource" Value="{Binding Source={StaticResource DirectionTypesCVS}}"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
...