WPF - DataGridComboBoxColumn 第一行的不同 ItemsSource

WPF - Different ItemsSource for first row of DataGridComboBoxColumn

我有一个包含多个列的 DataGrid,其中包括一个 DataGridComboBoxColumn。

我希望 ComboBox 只为第一行提供有限的选择。

<DataGridComboBoxColumn x:Name="myDataGrid"
                                    SelectedItemBinding="{Binding Direction,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
                                    ItemsSource="{Binding Source={StaticResource DirectionTypesCVS}}"
                                    Header="Direction" 
                                    Width="*"/>

我的 DirectionTypeCVS 是一个 CollectionViewSource,returns 一个 DirectionType 枚举列表,“NORTH, EAST, SOUTH, WEST”。对于第一行,我想将其限制为“NORTH”和“SOUTH”。

我已经尝试更改代码隐藏中的 ItemsSource,但这并不正确。我还尝试添加 CollectionViewSource 过滤器,但它似乎没有被正确应用。

正确的做法是什么?

我建议您使用 DataGridTemplateColumn 而不是 DataGridComboBoxColumn,这样您就可以绑定该行并找到 AlternationIndex。您需要做的是编写一个转换器。

<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.");
    }
}

如果将 DataGridAlternationCount 属性 设置为 int.MaxValue 并将 StyleDataTrigger 绑定到 ItemsControl.AlternationIndex 附加 属性 父 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>
        ...