如何检查一行是否有奇数?

时间:2012-06-10 11:36:16

标签: wpf xaml multidatatrigger

我正在尝试使用XAML为奇数行设置不同的颜色。

有问题的数据网格有3种不同类型的数据,我想用不同的颜色,只是改变AlternatingRowBackground不会。

我打算使用像

这样的东西
<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
         <Condition Binding="{Binding Type}" Value="0"/>                         
         <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/> 
         <Condition Binding="{Binding IsOddRow, RelativeSource={RelativeSource Self}}" Value="False"/>
    </MultiDataTrigger.Conditions>      
    <Setter Property="Background" Value="#FFDFE6ED"/>                   
</MultiDataTrigger>

似乎没有IsOddRow这样的属性。我应该检查什么属性?

3 个答案:

答案 0 :(得分:3)

您可以在AlternationCount上设置DataGrid,然后绑定到祖先DataGridRows附加属性ItemsControl.AlternationIndex。如果值为“1”,则您有一个奇数行号。

<DataGrid ItemsSource="{Binding ...}"
          AlternationCount="2">
    <DataGrid.CellStyle>
        <Style TargetType="DataGridCell">
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Type}" Value="0"/>
                        <Condition Binding="{Binding RelativeSource={RelativeSource Self},
                                                     Path=IsSelected}"
                                   Value="False"/>
                        <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}},
                                                     Path=(ItemsControl.AlternationIndex)}"
                                   Value="1"/>
                    </MultiDataTrigger.Conditions>
                    <Setter Property="Background" Value="#FFDFE6ED"/>
                </MultiDataTrigger>
                <!-- ... -->
            </Style.Triggers>
        </Style>
    </DataGrid.CellStyle>
    <!-- ... -->
</DataGrid>

请注意,绑定到附加属性时,必须在附加属性周围添加括号。 Path=(ItemsControl.AlternationIndex)会有效,但Path=ItemsControl.AlternationIndex不会。


<强>更新
您还可以通过附加行为创建属性IsOddRow。在您订阅LoadingRow的行为中。在事件处理程序中,您获取已加载行的索引并检查它是否为奇数。然后将结果存储在一个名为IsOddRow的附加属性中,您可以绑定它。

要开始行为,请将behaviors:DataGridBehavior.ObserveOddRow="True"添加到DataGrid

<DataGrid ItemsSource="{Binding ...}"
          behaviors:DataGridBehavior.ObserveOddRow="True">
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Type}" Value="0"/>
                        <Condition Binding="{Binding Path=IsSelected,
                                                     RelativeSource={RelativeSource Self}}" Value="False"/>
                        <Condition Binding="{Binding Path=(behaviors:DataGridBehavior.IsOddRow),
                                                     RelativeSource={RelativeSource Self}}" Value="False"/>
                    </MultiDataTrigger.Conditions>
                    <Setter Property="Background" Value="#FFDFE6ED"/>
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.RowStyle>
</DataGrid>

DataGridBehavior

public class DataGridBehavior
{
    #region ObserveOddRow

    public static readonly DependencyProperty ObserveOddRowProperty =
        DependencyProperty.RegisterAttached("ObserveOddRow",
                                            typeof(bool),
                                            typeof(DataGridBehavior),
                                            new UIPropertyMetadata(false, OnObserveOddRowChanged));
    [AttachedPropertyBrowsableForType(typeof(DataGrid))]
    public static bool GetObserveOddRow(DataGrid dataGrid)
    {
        return (bool)dataGrid.GetValue(ObserveOddRowProperty);
    }
    public static void SetObserveOddRow(DataGrid dataGrid, bool value)
    {
        dataGrid.SetValue(ObserveOddRowProperty, value);
    }

    private static void OnObserveOddRowChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
    {
        DataGrid dataGrid = target as DataGrid;
        dataGrid.LoadingRow += (object sender, DataGridRowEventArgs e2) =>
        {
            DataGridRow dataGridRow = e2.Row;
            bool isOddRow = dataGridRow.GetIndex() % 2 != 0;
            SetIsOddRow(dataGridRow, isOddRow);
        };
    }

    #endregion // ObserveOddRow

    #region IsOddRow

    public static DependencyProperty IsOddRowProperty =
        DependencyProperty.RegisterAttached("IsOddRow",
                                            typeof(bool),
                                            typeof(DataGridBehavior),
                                            new PropertyMetadata(false));
    [AttachedPropertyBrowsableForType(typeof(DataGridRow))]
    public static bool GetIsOddRow(DataGridRow dataGridCell)
    {
        return (bool)dataGridCell.GetValue(IsOddRowProperty);
    }
    public static void SetIsOddRow(DataGridRow dataGridCell, bool value)
    {
        dataGridCell.SetValue(IsOddRowProperty, value);
    }

    #endregion // IsOddRow
}

答案 1 :(得分:2)

我不确定您使用的是哪种网格/行类型,因此我无法提供确切的属性名称,但是,绑定到行的索引(行号)并使用value converter(返回是)检查行是奇数还是偶数。

答案 2 :(得分:0)

几乎每个答案都使用AlternationCount="2",但我觉得它有点太局限了。在我这边,我使用AlternationCount="{ Binding MainData.ProjColl.Count}"之类的东西来编号我的行直到结束(注意它从0开始!)。

在这种情况下,我需要@Danny Varod提到的值转换器。

我使用转换器来交替行的颜色(几乎回答问题)

public class IsEvenConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        bool res = false;
        int? val = value as int?;
        if (null != val)
            res = (0 == (val % 2));
        return res;
    }     
    ...
}

和调用XAML

<UserControl ...
<UserControl.Resources>
    ...
    <vm_nmspc:IsEvenConverter x:Key="IsEven"/>
    <Style TargetType="DataGridRow">
        <Setter Property="Width" Value="Auto"/>
        <Setter Property="Background" Value="LightGray"/>

        <!--Converter will be used below-->

        <Style.Triggers>
            ...
            <Setter Property="Background" Value="LightGray"/
            <DataTrigger Binding="{Binding  RelativeSource={RelativeSource Self},
                                            Path=(ItemsControl.AlternationIndex),
                                            Converter={StaticResource ResourceKey=IsEven}}" Value="true">
                <Setter Property="Background" Value="Lavender"/>
            </DataTrigger>
            <Trigger Property="IsMouseOver" Value="True" >
                <Setter Property="Background" Value="LightGreen"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>

<Grid>
    <DataGrid ItemsSource="{Binding MainData.ProjColl}" AutoGenerateColumns="False" 
    AlternationCount="{ Binding MainData.ProjColl.Count}" >
    ...
    <DataGridTextColumn Header="Project Name" .... 

    </DataGrid>
</Grid>
</UserControl>

和一些离散的屏幕截图

enter image description here enter image description here

相同代码的另一部分: Simple way to display row numbers on WPF DataGrid