DataGrid 处于非活动状态时选择的行颜色

发布于 2024-12-13 09:56:05 字数 54 浏览 0 评论 0 原文

当 DataGrid 失去焦点时,如何设置 WPF DataGrid 样式以更改所选行的颜色?

How can I style WPF DataGrid to change the color of selected row when DataGrid lost its focus?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

心凉 2024-12-20 09:56:05

经过多年的搜索,我发现了一种令人惊讶的简单方法,比之前发布的 Got/LostFocus 方法更清晰:

<DataGrid.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="DarkGray"/>
</DataGrid.Resources>

这只是将非活动背景颜色设置为 DarkGray,将活动背景颜色保留为默认值,但您也可以更改它当然也使用 SystemColors.HighlightBrushKey 。

非活动选择的前台资源键是 SystemColors.InactiveSelectionHighlightTextBrushKey。

After ages of searching, I found a surprisingly simple way to do this that's cleaner than the Got/LostFocus approach posted earlier:

<DataGrid.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="DarkGray"/>
</DataGrid.Resources>

This just sets the inactive background colour to DarkGray, leaving the active background colour to the default, but you can change that too using the SystemColors.HighlightBrushKey too of course.

The foreground resource key for inactive selections is SystemColors.InactiveSelectionHighlightTextBrushKey.

别想她 2024-12-20 09:56:05

适用于 4.0 的完整解决方案。请注意,这在 CellStyle 上。

<DataGrid.CellStyle>
    <!--Override Highlighting so that its easy to see what is selected even when the control is not focused-->
    <Style TargetType="{x:Type DataGridCell}">
        <Style.Triggers>
            <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>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True" />
                    <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=IsKeyboardFocusWithin}" Value="False" />
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <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}}" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
</DataGrid.CellStyle>

Complete solution that works for 4.0. Note that this on the CellStyle.

<DataGrid.CellStyle>
    <!--Override Highlighting so that its easy to see what is selected even when the control is not focused-->
    <Style TargetType="{x:Type DataGridCell}">
        <Style.Triggers>
            <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>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True" />
                    <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=IsKeyboardFocusWithin}" Value="False" />
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <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}}" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
</DataGrid.CellStyle>
傲娇萝莉攻 2024-12-20 09:56:05

这样做:

<DataGrid ...>
    <DataGrid.Resources> 
        <Style TargetType="DataGridRow"> 
            <Style.Resources> 
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red"/>                                  
            </Style.Resources> 
        </Style> 
   </DataGrid.Resources> 
...

Do it like this:

<DataGrid ...>
    <DataGrid.Resources> 
        <Style TargetType="DataGridRow"> 
            <Style.Resources> 
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red"/>                                  
            </Style.Resources> 
        </Style> 
   </DataGrid.Resources> 
...
聽兲甴掵 2024-12-20 09:56:05

这些答案都没有给我我想要的东西。 Steve Streeting 评价最高的答案更改了我不想更改的数据网格的其他部分,而其他答案没有提供非活动颜色更改,而是仅正确定位了该行。因此,这里是他们的答案的混合,这些答案改变了非活动颜色,在行上,而不是在网格的其他位置。

<DataGrid.Resources>
    <Style TargetType="DataGridRow">
        <Style.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="DarkGray"/>
        </Style.Resources>
    </Style>
</DataGrid.Resources>

None of these answers gave me quite what I was looking for. The top rated by Steve Streeting changed other sections of the datagrid that I didn't want to change, and other answers weren't providing the inactive color change, but were properly targeting the row only. So here's a mixture of their answers that changes the inactive color, only on the rows and not in other places on the grid.

<DataGrid.Resources>
    <Style TargetType="DataGridRow">
        <Style.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="DarkGray"/>
        </Style.Resources>
    </Style>
</DataGrid.Resources>
嘦怹 2024-12-20 09:56:05

最新答案:

这适用于.Net 4.0,并且您不必对颜色进行硬编码:

<Style TargetType="DataGridRow">
    <Style.Resources>
         <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{x:Static SystemColors.HighlightColor}" />
         <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="{x:Static SystemColors.HighlightTextColor}"/>
    </Style.Resources>
</Style>

LATE ANSWER:

This works in .Net 4.0, and you don't have to hardcode the color:

<Style TargetType="DataGridRow">
    <Style.Resources>
         <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{x:Static SystemColors.HighlightColor}" />
         <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="{x:Static SystemColors.HighlightTextColor}"/>
    </Style.Resources>
</Style>
睫毛上残留的泪 2024-12-20 09:56:05

对于 .Net Framework 4.0(或者如果您不想使用 InactiveSelection... 画笔键):
创建一个 DataGridRow 样式/控件模板,并添加以下触发器:

<ControlTemplate.Triggers>
    <Trigger  Property="IsSelected" Value="true">
        <Setter Property="Background" Value="{DynamicResource SelectionBrush}" />
    </Trigger>
    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True" />
            <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=IsKeyboardFocusWithin}" Value="False" />
        </MultiDataTrigger.Conditions>
        <MultiDataTrigger.Setters>
            <Setter Property="Background" Value="{DynamicResource InactiveSelectionBrush}" />
        </MultiDataTrigger.Setters>
    </MultiDataTrigger>
</ControlTemplate.Triggers>

For .Net Framework 4.0 (or if you don't want to use the InactiveSelection... brush keys):
Create a DataGridRow style/control template, and add these triggers:

<ControlTemplate.Triggers>
    <Trigger  Property="IsSelected" Value="true">
        <Setter Property="Background" Value="{DynamicResource SelectionBrush}" />
    </Trigger>
    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True" />
            <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=IsKeyboardFocusWithin}" Value="False" />
        </MultiDataTrigger.Conditions>
        <MultiDataTrigger.Setters>
            <Setter Property="Background" Value="{DynamicResource InactiveSelectionBrush}" />
        </MultiDataTrigger.Setters>
    </MultiDataTrigger>
</ControlTemplate.Triggers>
神也荒唐 2024-12-20 09:56:05

我将其添加到我的 ResourceDictionary 中,以便它适用于我的程序中的所有数据网格。

<Style TargetType="DataGrid">
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="LightGray"/>
    </Style.Resources>        
</Style>

I added this to my ResourceDictionary so that it applies to all data grids in my program.

<Style TargetType="DataGrid">
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="LightGray"/>
    </Style.Resources>        
</Style>
浮生面具三千个 2024-12-20 09:56:05

您应该在 DataGrid 中定义“DataGrid.CellStyle”部分,如下所示:

    <DataGrid>
        <DataGrid.CellStyle>
            <Style TargetType="DataGridCell">
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Background" Value="LightBlue"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </DataGrid.CellStyle>
    </DataGrid>

You should define section "DataGrid.CellStyle" inside your DataGrid like this:

    <DataGrid>
        <DataGrid.CellStyle>
            <Style TargetType="DataGridCell">
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Background" Value="LightBlue"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </DataGrid.CellStyle>
    </DataGrid>
倦话 2024-12-20 09:56:05

自己找答案吧。

将画笔添加到 DataGrid 的资源中,该画笔可以从后面的代码更改其“Color”属性,并对其引用 HighlightBrushKey:

<DataGrid.Resources>
    <SolidColorBrush x:Key="SelectionColorKey" Color="DarkGray"/>
    <Style TargetType="DataGridRow">
        <Style.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{Binding Source={StaticResource SelectionColorKey}, Path=Color}"/>
        </Style.Resources>
    </Style>
</DataGrid.Resources>

然后添加 DataGrids 事件处理程序以手动更改颜色:

private void DataGrid1_LostFocus(object sender, RoutedEventArgs e)
{
    ((SolidColorBrush)DataGrid1.Resources["SelectionColorKey"]).Color = Colors.DarkGray;
}

private void DataGrid1_GotFocus(object sender, RoutedEventArgs e)
{
    ((SolidColorBrush)DataGrid1.Resources["SelectionColorKey"]).Color = SystemColors.HighlightColor;
}

private void DataGrid1_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    ((SolidColorBrush)DataGrid1.Resources["SelectionColorKey"]).Color = Colors.DarkGray;
}

Find an answer by myself.

Add to DataGrid's resources the brush, which can change its 'Color' property from code behind, and reference HighlightBrushKey to it:

<DataGrid.Resources>
    <SolidColorBrush x:Key="SelectionColorKey" Color="DarkGray"/>
    <Style TargetType="DataGridRow">
        <Style.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{Binding Source={StaticResource SelectionColorKey}, Path=Color}"/>
        </Style.Resources>
    </Style>
</DataGrid.Resources>

Then add DataGrids event handlers to manually change the color:

private void DataGrid1_LostFocus(object sender, RoutedEventArgs e)
{
    ((SolidColorBrush)DataGrid1.Resources["SelectionColorKey"]).Color = Colors.DarkGray;
}

private void DataGrid1_GotFocus(object sender, RoutedEventArgs e)
{
    ((SolidColorBrush)DataGrid1.Resources["SelectionColorKey"]).Color = SystemColors.HighlightColor;
}

private void DataGrid1_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    ((SolidColorBrush)DataGrid1.Resources["SelectionColorKey"]).Color = Colors.DarkGray;
}
海风掠过北极光 2024-12-20 09:56:05

对于 .net Framework 4.0

<Style TargetType="DataGridRow">
 <Style.Resources>
     <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="DarkGray" />
     <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="White"/>
 </Style.Resources>
</Style>

https://social.msdn.microsoft.com/Forums/vstudio/en-US/635642e6-4808-4b3e-8aea-c8c434397d0f/datagrid-lost-focus-brush?forum=wpf

For .net Framework 4.0

<Style TargetType="DataGridRow">
 <Style.Resources>
     <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="DarkGray" />
     <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="White"/>
 </Style.Resources>
</Style>

https://social.msdn.microsoft.com/Forums/vstudio/en-US/635642e6-4808-4b3e-8aea-c8c434397d0f/datagrid-lost-focus-brush?forum=wpf

萌化 2024-12-20 09:56:05

对于.NET 4.0或更高版本:还可以以编程方式设置颜色:

if (TestDataGrid.RowStyle == null)
{
  TestDataGrid.RowStyle = new Style(typeof(DataGridRow));
}

// Set colors for the selected rows if focus is inactive
TestDataGrid.RowStyle.Resources.Add(SystemColors.ControlBrushKey, new SolidColorBrush(Colors.SkyBlue));
TestDataGrid.RowStyle.Resources.Add(SystemColors.ControlTextBrushKey, new SolidColorBrush(Colors.Black));

// Set colors for the selected rows if focus is active
TestDataGrid.RowStyle.Resources.Add(SystemColors.HighlightBrushKey, new SolidColorBrush(Colors.Red));
TestDataGrid.RowStyle.Resources.Add(SystemColors.HighlightTextBrushKey, new SolidColorBrush(Colors.White));

对于.NET 4.5或更高版本,有以下替代方案以编程方式设置颜色:

if (TestDataGrid.Resources == null)
{
  TestDataGrid.Resources = new ResourceDictionary();
}

// Set colors for the selected rows if focus is inactive
TestDataGrid.Resources.Add(SystemColors.InactiveSelectionHighlightBrushKey, new SolidColorBrush(Colors.SkyBlue));
TestDataGrid.Resources.Add(SystemColors.InactiveSelectionHighlightTextBrushKey, new SolidColorBrush(Colors.Black));

// Set colors for the selected rows if focus is active
TestDataGrid.Resources.Add(SystemColors.HighlightBrushKey, new SolidColorBrush(Colors.Red));
TestDataGrid.Resources.Add(SystemColors.HighlightTextBrushKey, new SolidColorBrush(Colors.White));

For .NET 4.0 or higher: It is also possible to set the colors programmatically:

if (TestDataGrid.RowStyle == null)
{
  TestDataGrid.RowStyle = new Style(typeof(DataGridRow));
}

// Set colors for the selected rows if focus is inactive
TestDataGrid.RowStyle.Resources.Add(SystemColors.ControlBrushKey, new SolidColorBrush(Colors.SkyBlue));
TestDataGrid.RowStyle.Resources.Add(SystemColors.ControlTextBrushKey, new SolidColorBrush(Colors.Black));

// Set colors for the selected rows if focus is active
TestDataGrid.RowStyle.Resources.Add(SystemColors.HighlightBrushKey, new SolidColorBrush(Colors.Red));
TestDataGrid.RowStyle.Resources.Add(SystemColors.HighlightTextBrushKey, new SolidColorBrush(Colors.White));

For .NET 4.5 or higher there is the following alternative to set the colors programmatically:

if (TestDataGrid.Resources == null)
{
  TestDataGrid.Resources = new ResourceDictionary();
}

// Set colors for the selected rows if focus is inactive
TestDataGrid.Resources.Add(SystemColors.InactiveSelectionHighlightBrushKey, new SolidColorBrush(Colors.SkyBlue));
TestDataGrid.Resources.Add(SystemColors.InactiveSelectionHighlightTextBrushKey, new SolidColorBrush(Colors.Black));

// Set colors for the selected rows if focus is active
TestDataGrid.Resources.Add(SystemColors.HighlightBrushKey, new SolidColorBrush(Colors.Red));
TestDataGrid.Resources.Add(SystemColors.HighlightTextBrushKey, new SolidColorBrush(Colors.White));
熟人话多 2024-12-20 09:56:05

我有类似的问题。
该场景是一个 DataGrid,其颜色分配给:
行背景和交替行背景。
当 DataGrid 失去焦点时,所选行将变为灰色,当 DataGrid 通过单击任何行重新获得焦点时,将返回到正确的颜色。
这种效果是令人不愉快的。
我从 Steve Streeting 此处提出的解决方案开始:

<Style TargetType="DataGrid">
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" 
                         Color="LightGray"/>
    </Style.Resources>
</Style>

但是通过更改 Color =“Transparent”。

<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" 
                 Color="Transparent"/>

这以简单且令人满意的方式解决了问题。
.net 4.5 有效,不适用于 .net 4.0

希望这个解决方案是有用的

不正确的行为:

不正确的行为

正确的行为:

正确行为

I had a similar problem.
The scenario was a DataGrid with colors assigned for:
RowBackground and AlternatingRowBackground.
When the DataGrid Lose Focus, the selected row became Gray, returning to the correct color when the DataGrid regained Focus by clicking on any row.
This effect was unpleasant.
I started from the solution proposed here by Steve Streeting:

<Style TargetType="DataGrid">
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" 
                         Color="LightGray"/>
    </Style.Resources>
</Style>

but by changing Color = "Transparent".

<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" 
                 Color="Transparent"/>

this solved the problem in a simple and satisfactory way.
valid for .net 4.5, not for .net 4.0.

Hope this solution is useful

incorrect behavior:

incorrect behavior

correct behavior:

correct behavior

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文