user3471081
user3471081

Reputation: 21

WPF DataGrid IsSelected Foreground Colour Change Dinamically

in My app I have a DataGrid, that changes colour (Background and Foreground) depending on the data. To do this I use DataTriggers that compare the value to set the colour accordingly.

<DataGrid ItemsSource="{Binding listProducts, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding selectedProduct}">
   <DataGrid.RowStyle>
      <Style TargetType="DataGridRow">
         <Setter Property="Background" Value="{StaticResource OverStockBackground}" />
         <Style.Triggers>
            <DataTrigger Binding="{Binding Path=stockVsMin}" Value="1">
               <Setter Property="Background" Value="{StaticResource NoStockBackground}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=Added}" Value="true">
               <Setter Property="Foreground" Value="Red" />
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </DataGrid.RowStyle>
   <DataGrid.CellStyle>
      <Style TargetType="DataGridCell">
         <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
               <Setter Property="Background" Value="{x:Null}" />
               <Setter Property="BorderThickness" Value="1" />
            </Trigger>
         </Style.Triggers>
      </Style>
   </DataGrid.CellStyle>
   <DataGrid.Columns>
      <DataGridTextColumn Header="Code" Binding="{Binding Code}" />
      <DataGridTextColumn Header="Description" Binding="{Binding Description}" />
      <DataGridTextColumn Header="Stock" Binding="{Binding Stock}" />
      <DataGridTextColumn Header="stockVsMin" Binding="{Binding stockVsMin}" />
      <DataGridTextColumn Header="Added" Binding="{Binding Added}" />
   </DataGrid.Columns>
</DataGrid>

With that style, the Background does not changes when the row is selected, but the Foreground does, it turns White as per the Default IsSelected behaviour.

So I tried the same thing as with the background, but the problem is that with the Foreground, if I set it to {x:Null} or transparent the words disappear, so I know it is changing it anyway. If I set the IsSelected Foreground to

<Style.Triggers>
  <Trigger Property="IsSelected" Value="True">
      <Setter Property="Foreground"
              Value="{Binding RelativeSource={RelativeSource Self},
                              Path=Foreground}" />
  </Trigger>
<Style.Triggers>

It takes the value of the Foreground on the moment you selected the row, but it stops being dynamic, so if the value changes and the row is selected, it does not changes the colour until you select something else. I tried to do a new template (Right Click => Edit Aditional Template => Edit a Copy) and I just deleted the Foreground from the style, but it changes anyway.

Any help is appreciated.

Upvotes: 1

Views: 867

Answers (1)

EldHasp
EldHasp

Reputation: 7943

Since the DataGrid provides a mode for selecting individual cells, and not just the entire row, the style changes for the selected elements occur at the DataGridCell level.

Here is the default cell template.
In it, I marked the triggers responsible for changes when a cell is selected.

<Style x:Key="DataGridCellStyle1" TargetType="{x:Type DataGridCell}">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>

            <!--Highlighting when DataGrid has focus (Selector.IsSelectionActive = "true").-->
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
            <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
        </Trigger>
        <Trigger Property="IsKeyboardFocusWithin" Value="True">
            <Setter Property="BorderBrush" Value="{DynamicResource {x:Static DataGrid.FocusBorderBrushKey}}"/>
        </Trigger>

        <!--Highlighting when DataGrid is out of focus.-->
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsSelected" Value="true"/>
                <Condition Property="Selector.IsSelectionActive" Value="false"/>
            </MultiTrigger.Conditions>
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
            <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
        </MultiTrigger>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
        </Trigger>
    </Style.Triggers>
</Style>

The cell style is set in the property <DataGrid CellStyle="{DynamicResource DataGridCellStyle1}">

It is not necessary to re-create the entire style with a template.
Since resources are accessed through the DynamicResource, to change the selection colors, you need to set new values for these resources in the DataGrid resources or at higher levels.

Examle:

    <Grid>
        <FrameworkElement.Resources> 
            <SolidColorBrush
                x:Key="{x:Static SystemColors.HighlightBrushKey}"
                Color="LightGreen"/>
            <SolidColorBrush
                x:Key="{x:Static SystemColors.HighlightTextBrushKey}"
                Color="Blue"/>
            <SolidColorBrush
                x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}"
                Color="Yellow"/>
            <SolidColorBrush
                x:Key="{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}"
                Color="LightBlue"/>
        </FrameworkElement.Resources>
        <DataGrid ItemsSource=.....

Upvotes: 1

Related Questions