如何在DataGrid中设置选定行的颜色

142

在DataGrid中,所选行的默认背景颜色太暗了,我无法阅读它。有没有什么方法可以覆盖它?

尝试过这个:

<dg:DataGrid.RowStyle>
    <Style TargetType="{x:Type dg:DataGridRow}">
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True" >
                <Setter Property="Background" Value="Gainsboro" />
            </Trigger>
        </Style.Triggers>
    </Style>
</dg:DataGrid.RowStyle>

但仍然没有任何进展...

8个回答

177
上述解决方案在我的情况下在每个单元格周围留下了蓝色边框。
这是对我有用的解决方案。它非常简单,只需将其添加到您的中即可。您可以将其从SolidColorBrush更改为任何其他刷子,如线性渐变。
<DataGrid.Resources>
  <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" 
                   Color="#FF0000"/>
</DataGrid.Resources>

6
非常棒。你有任何关于前景颜色如何做到同样效果的想法吗? - Arsen Zahray
10
Arsen,只需以同样的方式覆盖SystemColors.HighlightTextBrushKey的刷子来设置文本颜色。 - Ben McIntosh
7
最终找到了一个,如果没有焦点则为SystemColors.ControlBrushKey - Rolfi
3
@B.K. 可能是 SystemColors.InactiveSelectionHighlightBrushKey - Gerard
1
这是一个非常好的解决方案,除了一个问题...当我点击单元格以突出显示一行时,我会得到一个黑色边框围绕所选单元格。我能够使用这个解决方案在这里去掉边框。 - Smitty-Werben-Jager-Manjenson
显示剩余5条评论

118

明白了。在DataGrid.Resources部分中添加以下内容:

  <DataGrid.Resources>
     <Style TargetType="{x:Type dg:DataGridCell}">
        <Style.Triggers>
            <Trigger Property="dg:DataGridCell.IsSelected" Value="True">
                <Setter Property="Background" Value="#CCDAFF" />
            </Trigger>
        </Style.Triggers>
    </Style>
</DataGrid.Resources>

太好了,我刚遇到这个问题,感到非常沮丧 :-) - Rob
7
你要把它放在哪个部分? - Colonel Panic
9
由于“BorderBrush”属性保持为蓝色,如果这让某人感到不适,只需添加另一个“Setter”元素,将“BorderBrush”依赖属性设置为与“Background”本身相同的颜色(值)。 - aniski

87

作为对 @Seb Kade 回答的扩展,您可以使用以下 Style 来完全控制所选行和未选行的颜色:

<Style TargetType="{x:Type DataGridRow}">
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
    </Style.Resources>
</Style>

你当然可以输入任何你喜欢的颜色。这个Style也适用于其他集合项,例如ListBoxItems(如果你将TargetType = "{x:Type DataGridRow}"替换为TargetType = "{x:Type ListBoxItem}"等)。


7
你的解决方案是最好的一个。 - NoWar
不错,Sheridan。我也想要在选定行上设置我的行的前景色。但是它使用默认的HighlightTextBrushKey(即黑色)。该怎么办? - deathrace
1
@deathrace.dj,如果我理解正确的话,你只需要将我的示例中第三个SolidColorbrushColor属性更改为您喜欢的任何颜色。使用此声明实际上是设置SystemColors.HighlightTextBrushKey使用的SolidColorbrush的颜色。但要小心,您没有在其他地方设置Style中的Foreground颜色,因为这可能会覆盖上面的Resources中的设置。 - Sheridan
4
你可能还希望为SystemColors.InactiveSelectionHighlightBrushKey设置一个透明的画笔,否则当表格失去焦点时,该行会被突出显示。 - dlf
有没有一个SystemColor可以覆盖,以全局改变禁用单元格的前景色?谢谢。 - Davide Capodaglio
很棒的解决方案,让我明白了为什么我选择的行颜色与点击的行颜色不同(我使用SelectionUnit="FullRow")。 - Andrea Antonangeli

20

我也遇到了这个问题,找了很久没在网上找到正确的答案。我试图控制WPF DataGrid中选定行的背景颜色,但一直都做不到。后来发现是因为我的datagrid里还有一个CellStyle,它重写了我设置的RowStyle。有趣的是,CellStyle并没有设置背景颜色,而是由RowBackground和AlternateRowBackground属性设置的。尽管如此,当我尝试设置选定行的背景颜色时,这样做根本行不通:

        <DataGrid ... >
        <DataGrid.RowBackground>
            ...
        </DataGrid.RowBackground>
        <DataGrid.AlternatingRowBackground>
            ...
        </DataGrid.AlternatingRowBackground>
        <DataGrid.RowStyle>
            <Style TargetType="{x:Type DataGridRow}">
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Background" Value="Pink"/>
                        <Setter Property="Foreground" Value="White"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </DataGrid.RowStyle>
        <DataGrid.CellStyle>
            <Style TargetType="{x:Type DataGridCell}">
                <Setter Property="Foreground" Value="{Binding MyProperty}" />
            </Style>
        </DataGrid.CellStyle>

当我将所选行的期望样式从行样式移动到单元格样式时,它确实起作用了,就像这样:

    <DataGrid ... >
        <DataGrid.RowBackground>
            ...
        </DataGrid.RowBackground>
        <DataGrid.AlternatingRowBackground>
            ...
        </DataGrid.AlternatingRowBackground>
        <DataGrid.CellStyle>
            <Style TargetType="{x:Type DataGridCell}">
                <Setter Property="Foreground" Value="{Binding MyProperty}" />
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Background" Value="Pink"/>
                        <Setter Property="Foreground" Value="White"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </DataGrid.CellStyle>

我在这里发布这篇文章,以防有人遇到同样的问题。


每次都会发生这种情况,单元格设置前景色,每个人都会定位到该行。 - eran otzap
1
我也遇到了这个问题,而且我甚至没有设置 CellStyle。当我尝试在行样式上设置它时,它只影响非单元格元素。 - BigSandwich

13

默认的IsSelected触发器会改变3个属性,即背景、前景和边框画笔。如果您想要同时更改边框和背景,只需在样式触发器中包含这个。

<Style TargetType="{x:Type dg:DataGridCell}">
    <Style.Triggers>
        <Trigger Property="dg:DataGridCell.IsSelected" Value="True">
            <Setter Property="Background" Value="#CCDAFF" />
            <Setter Property="BorderBrush" Value="Black" />
        </Trigger>
    </Style.Triggers>
</Style>

@Mark H,与其在这个时候对这个答案进行重大更改,不如添加你自己的答案。 - Michael Petrotta

12

我经历了一些导致行选择事件不起作用的原因:

  1. 为DataGridCell设置了样式
  2. 使用了模板列
  3. 在DataGridRow上设置了触发器

这是帮助我解决问题的方法。设置DataGridCell的样式。

<Style TargetType="{x:Type DataGridCell}">
  <Style.Triggers>
    <Trigger Property="IsSelected" Value="True">
      <Setter Property="Background" Value="Green"/>
      <Setter Property="Foreground" Value="White"/>
    </Trigger>
  </Style.Triggers> 
</Style>

由于我在使用模板列时,里面有一个标签,所以我使用相对源绑定将Foreground属性绑定到容器的Foreground:

<DataGridTemplateColumn>
  <DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
      <Label Content="{Binding CategoryName,
                 Mode=TwoWay,
                 UpdateSourceTrigger=LostFocus}"
             Foreground="{Binding Foreground,
                 RelativeSource={RelativeSource Mode=FindAncestor,
                     AncestorLevel=1, 
                     AncestorType={x:Type DataGridCell}}}"
             Width="150"/>
    </DataTemplate>
  </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

4

我曾尝试使用ControlBrushKey,但对未选行无效。未选行的背景仍然是白色。但我发现我必须重写行样式。

<DataGrid x:Name="pbSelectionDataGrid" Height="201" Margin="10,0"
          FontSize="20" SelectionMode="Single" FontWeight="Bold">
    <DataGrid.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#FFFDD47C"/>
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#FFA6E09C"/>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Red"/>
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Violet"/>
    </DataGrid.Resources>
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="Background" Value="LightBlue" />
        </Style>
    </DataGrid.RowStyle>
</DataGrid>

2

我花了一整天的时间来解决这个问题。结果发现,我设置的DataGrid中的RowBackground属性覆盖了所有尝试在CSS中更改它的方法。当我删除它时,一切都正常了。(顺便说一句,DataGridTextColumn中设置的Foreground也是如此。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接