Search code examples
wpftemplatesbindingdatagriddatagridrow

How to set DataGridRow Color and alternating row color in WPF?


How do I set the DataGridRow color to the DataGrid dependency property RowBackground?

<Style TargetType="{x:Type DataGrid}" x:Key="EmployeeDataGridStyle">

  <Setter Property="RowBackground" Value="White"/>
  <Setter Property="AlternatingRowBackground" Value="LightCyan"/>
  ...
</Style>

<Style TargetType="{x:Type DataGridRow}" x:Key="EmployeeDataGridRowStyle">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type DataGridRow}">
        <Border x:Name="DGR_Border"
                BorderBrush="{TemplateBinding BorderBrush}"
                BorderThickness="{TemplateBinding BorderThickness}"
                Background = { ??? //set this to the datagrid rowbackground }
                >
                ...
          <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Normal_AlternatingRow">
                <Storyboard>
                  <ColorAnimation
                    Storyboard.TargetName="DGR_Border"
                    Storyboard.TargetProperty="Background.Color"
                    Duration="0"
                    To="{ ??? // AlternatingRowBackground color that is set in the datagrid
                    >
                    ...

I am trying to set the DataGridRow color in the template to the DataGrid RowBackgroundColor property and trying to set the alternating row color using visual states to the AlternatingRowColor property of the DataGrid. How do I achieve this ?


Solution

  • The binding to RowBackground of the DataGrid can be done using a RelativeSource binding.

    Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=RowBackground}"
    

    However, the second binding in ColorAnmination on the To property is impossible by design.

    You can't use dynamic resource references or data binding expressions to set Storyboard or animation property values. That's because everything inside a ControlTemplate must be thread-safe, and the timing system must FreezeStoryboard objects to make them thread-safe. A Storyboard cannot be frozen if it or its child timelines contain dynamic resource references or data binding expressions. For more information about freezing and other Freezable features, see the Freezable Objects Overview.

    You can bind AlternatingRowBackground apart from animations the same way as above.

    Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=AlternatingRowBackground}"