Search code examples
wpfdatagridstylesattached-properties

Change background colour of a DataGrid column based on attached property


I am trying to style a DataGrid such that if a column has an attached property to indicate if it is highlighted. So those cells in a column where Highlighted = true would have a different colour to those columns with Highlighted = false.

My attached property looks like:

public static class Highlighted
{
    public static bool GetIsHighlighted(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsHighlightedProperty);
    }

    public static void SetIsHighlighted(DependencyObject obj, bool value)
    {
        obj.SetValue(IsHighlightedProperty, value);
    }

    public static readonly DependencyProperty IsHighlightedProperty =
        DependencyProperty.RegisterAttached("IsHighlighted", typeof(bool), typeof(Highlighted), new UIPropertyMetadata(false));
}

And the DataGridCell style looks like:

<Style x:Key="WeldOfficeDataGridCell" TargetType="{x:Type DataGridCell}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <Border BorderBrush="{x:Static SystemColors.ActiveBorderBrush}"
                        BorderThickness="0.5"
                        Background="FloralWhite" SnapsToDevicePixels="True">
                    <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" 
                                      Content="{TemplateBinding Content}" 
                                      ContentStringFormat="{TemplateBinding ContentStringFormat}" 
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                      VerticalAlignment="Center"
                                      Margin="15,5,5,5" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

    <Style.Triggers>
        <Trigger Property="attachedProperties:Highlighted.IsHighlighted" Value="True">
            <Setter Property="Background">
                <Setter.Value>
                    <SolidColorBrush Color="Red" />
                </Setter.Value>
            </Setter>
        </Trigger>

        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background">
                <Setter.Value>
                    <SolidColorBrush Color="{DynamicResource AccentColor2}" />
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
</Style>

I am setting the property in the DataGrid like:

    <DataGrid Margin="27,17,0,0"
              Grid.Column="1"
              ItemsSource="{Binding FilterableBaseMaterials}" 
              AutoGenerateColumns="False" 
              SelectionMode="Single"
              HeadersVisibility="Column"
              CanUserAddRows="False"
              CanUserDeleteRows="False"
              CanUserResizeRows="False"
              Background="{x:Null}">

        <DataGrid.Resources>
            <helpers:BindingProxy x:Key="proxy" Data="{Binding}" />
        </DataGrid.Resources>

        <DataGrid.Columns>

            <DataGridTemplateColumn Header="Specification" IsReadOnly="True" attachedProperties:Highlighted.IsHighlighted="True">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock HorizontalAlignment="Left" Text="{Binding Specification}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            ...

But after several frustrating hours i cannot figure out how to get this to work, my Style.Trigger for the attached property is wrong as it never triggers the change in colour, i guess because i have the property attached to the column and not the DataGridCell but i cannot figure out how to get this to work, any help would be appreciated.


Solution

  • You are setting the IsHighlighted attached property of the column. This is not the same thing as setting it on the cell.

    You should set it on the cell that eventually gets created by the column. The only way you can do this in pure XAML is to define a CellStyle for the column:

    <DataGridTemplateColumn Header="Specification" IsReadOnly="True">
        <DataGridTemplateColumn.CellStyle>
            <Style TargetType="DataGridCell" BasedOn="{StaticResource WeldOfficeDataGridCell}">
                <Setter Property="attachedProperties:Highlighted.IsHighlighted" Value="True" />
            </Style>
        </DataGridTemplateColumn.CellStyle>
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock HorizontalAlignment="Left" Text="{Binding Specification}" />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>