1
votes

In Excel, the bluish background selection color appears to be semi-transparent, so the user can still see the true background color even when the cell is selected. How can the same effect be achieved with the WPF datagrid?

In my particular case, the cell's Background color is also binded to the view model. My initial impression is to use a trigger in the cell style:

  <Style.Triggers>
      <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="????"></Setter>
      </Trigger>
  </Style.Triggers>

Then somehow the Value should calculate to ... some combination of blue and the UnSelected Background color? I tried using a brush of transparent blue, the result does not blend with the previous cell background color.

2
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results.Federico Berasategui
attempted solution addedTekito

2 Answers

4
votes

What you have tried should actually work.

Look at this example:

<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource SampleDataSource}}">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="10*"/>
    </Grid.RowDefinitions>
    <Rectangle Fill="#FF0090FF"/>
    <DataGrid Grid.Row="1" ItemsSource="{Binding TestCollection}" Background="Purple">
        <DataGrid.Resources>
            <Style TargetType="DataGridRow">
                <Setter Property="Background" Value="Yellow"/>
            </Style>
            <Style TargetType="DataGridCell">
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="true">
                        <Setter Property="Background" Value="#6F0090FF"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </DataGrid.Resources>
    </DataGrid>
</Grid>

enter image description here

There is blue rectangle. With Fill property set to #FF0090FF. What you should notice is the fact that what you call "UnSelected Background color" is actually Background of DataGridRow.

And now... Background color of selected cell is exactly the same as Fill of that rectangle(#0090FF). I only changed Alpha to roughly 50%(#6F0090FF). And what you see is something greenish as you would expect.

enter image description here

UPDATE

When you want to preserve Background of DataGridCell then you have to choose different approach. I would suggest to create one more layer in your DataGridCell's ControlTemplate

This layer... we may call it for example "selectedCellVisual" will be visible only when cell is selected.

So... we have to create ControlTemplate thus we have to change Style of DataGridCell from previous example.

<Style TargetType="DataGridCell" >
                <Setter Property="OverridesDefaultStyle" Value="True"/>
                <Setter Property="Background" Value="Red"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type DataGridCell}">
                            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                                <Grid>
                                    <Rectangle x:Name="selectedCellVisual" Fill="#6F0090FF" Visibility="Collapsed"/>
                                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsSelected" Value="true">
                                    <Setter TargetName="selectedCellVisual" Property="Visibility" Value="Visible"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

Now DataGridCell has red Background and when it's selected then semi-transparent blue rectangle "selectedCellVisual" is visible. Transparent blue and red on background makes final violet color.

enter image description here

You should pay attention to

<Setter Property="OverridesDefaultStyle" Value="True"/>

It has to be there... because we didn't change trigger for IsSelected property which changes cell's background. It's defined in default style. It changes Background and Foreground properties. You can notice this in first example. Foreground is set white and there is one pixel wide blue line around cell.

1
votes

Based on this answer, I've found a solution with overriding of system colors for data grid, e.g. add some transparency for system highlight color and use regular text color during highlight:

    <DataGrid>

        <DataGrid.Resources>
            <SolidColorBrush 
                x:Key="{x:Static SystemColors.HighlightBrushKey}"
                Color="{DynamicResource {x:Static SystemColors.HighlightColorKey}}" 
                Opacity="0.2"/>
            <SolidColorBrush 
                x:Key="{x:Static SystemColors.HighlightTextBrushKey}" 
                Color="{DynamicResource {x:Static SystemColors.WindowTextColorKey}}"/>
        </DataGrid.Resources>

    ...