views:

42

answers:

2

How can I make columns coloring in DataGrid if I also want use AlternatingRowBackground property? I have some ideas, but it doesn't work :(.

<de:DataGrid Name="dataGrid1"
                             AlternationCount="2"
                             AlternatingRowBackground="Salmon"
                             >
                    <de:DataGrid.Columns>
                        <de:DataGridTextColumn Binding="{Binding Path=Phrase}"
                                               Header="Phrase">
                            <de:DataGridTextColumn.ElementStyle>
                                <Style TargetType="{x:Type TextBlock}">
                                    <Style.Triggers>
                                        <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                                            <Setter Property="Background" Value="Green"></Setter>
                                        </Trigger>
                                        <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                                            <Setter Property="Background" Value="Red"></Setter>
                                        </Trigger>

                                    </Style.Triggers>
                                </Style>
                            </de:DataGridTextColumn.ElementStyle>
                        </de:DataGridTextColumn>
                     </de:DataGrid.Columns>
                </de:DataGrid>

Maybe somebody knows working solution? Thanks.

A: 

You are searching AlternationIndex property in the wrong control. This property belongs to DataGridRow.

<DataGrid ItemsSource="{Binding}" AlternationCount="2" AutoGenerateColumns="False" AlternatingRowBackground="Salmon">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Path=Phrase}" Header="Phrase">
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="0">
                                    <Setter Property="Background" Value="Green"></Setter>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="1">
                                    <Setter Property="Background" Value="Red"></Setter>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>
            </DataGrid.Columns>
          </DataGrid>
vorrtex
A: 

If you want a more generic way to do this than you can use this pretty lengthy solution.

I have to say it can look pretty strange :-)

alt text
If we want to be able to put Background and AlternatingBackground on DataGridColumn then we need two attached properties

public static class GridColumnBackground
{
    private static readonly DependencyProperty ColumnBackgroundProperty = DependencyProperty.RegisterAttached(
      "ColumnBackground",
      typeof(Brush),
      typeof(GridColumnBackground)
      );
    public static void SetColumnBackground(DependencyObject element, Brush value)
    {
        element.SetValue(ColumnBackgroundProperty, value);
    }
    public static Brush GetColumnBackground(DependencyObject element)
    {
        return element.GetValue(ColumnBackgroundProperty) as Brush;
    }

    private static readonly DependencyProperty ColumnAlternatingBackgroundProperty = DependencyProperty.RegisterAttached(
      "ColumnAlternatingBackground",
      typeof(Brush),
      typeof(GridColumnBackground)
      );
    public static void SetColumnAlternatingBackground(DependencyObject element, Brush value)
    {
        element.SetValue(ColumnAlternatingBackgroundProperty, value);
    }
    public static Brush GetColumnAlternatingBackground(DependencyObject element)
    {
        return element.GetValue(ColumnAlternatingBackgroundProperty) as Brush;
    }
}

Then we need a style for DataGridCell

<Style x:Key="ColumnColoredCellStyle" TargetType="{x:Type DataGridCell}" >
    <Setter Property="BorderBrush" Value="Black" />
    <Setter Property="BorderThickness" Value="0,0,1,1" />
    <Setter Property="Background">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource CellBackgroundMultiConverter}">
                <Binding RelativeSource="{RelativeSource self}" Path="Column.(local:GridColumnBackground.ColumnBackground)" />
                <Binding RelativeSource="{RelativeSource self}" Path="Column.(local:GridColumnBackground.ColumnAlternatingBackground)" />
                <Binding RelativeSource="{RelativeSource AncestorType={x:Type DataGridRow}}" Path="AlternationIndex" />
            </MultiBinding>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Background" Value="#316AC5"/>
        </Trigger>
    </Style.Triggers>
</Style>

With a MultiConverter

public class CellBackgroundMultiConverter : IMultiValueConverter
{
    #region IMultiValueConverter Members

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        Brush backgroundColor = values[0] as Brush;
        Brush backgroundAlternatingColor = values[1] as Brush;
        int alternatingIndex = (int)values[2];
        if (alternatingIndex == 0)
        {
            return backgroundColor;
        }
        return backgroundAlternatingColor;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return null;
    }

    #endregion
}

And then we can set up the DataGrid like this

<DataGrid x:Name="c_dataGrid"
          AutoGenerateColumns="False"
          Background="Transparent"
          AlternatingRowBackground="Transparent"
          GridLinesVisibility="None"
          SelectionMode="Single"
          SelectionUnit="Cell"
          CellStyle="{StaticResource ColumnColoredCellStyle}">
    <DataGrid.Columns>
        <DataGridTextColumn local:GridColumnBackground.ColumnBackground="Gold"
                            local:GridColumnBackground.ColumnAlternatingBackground="LightGoldenrodYellow"
                            Header="Column 1"
                            Binding="{Binding Column1Property}"/>
        <!-- More Columns.. -->
    </DataGrid.Columns>
</DataGrid>
Meleak