选择时更改 DataGrid 中单个单元格的颜色,覆盖当前颜色
Change colour of single cell in DataGrid when selected, overriding current colour
我有这段代码会影响 DataGrid
:
的整行
<DataGrid x:Name="tblopenRequests" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="2"
IsReadOnly="true" RowHeaderWidth="0" AutoGenerateColumns="False" CanUserAddRows="False" SelectionMode="Single">
<DataGrid.Resources>
<Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}" TargetType="{x:Type DataGridColumnHeader}" >
<Setter Property="Background" Value="LightSeaGreen" />
<Setter Property="Foreground" Value="white" />
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="1 1 1 1"/>
<Setter Property="Margin" Value="-1,-1,0,0" />
<Setter Property="Height" Value="28" />
<Setter Property="Width" Value="auto"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>
<Style TargetType="DataGridCell">
<Setter Property="HorizontalContentAlignment" Value="Right" />
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="Goldenrod" />
<Setter Property="BorderBrush" Value="white" />
<Setter Property="Foreground" Value="black" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontSize" Value="15"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
我现在想用不同的格式覆盖行中的一个单元格以更加突出。
这就是我目前的全部,但我一直在尝试失败。
<DataGridTextColumn Binding="{Binding expectedDate}" Header="Expected Date" Width="90">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
我试过在此处添加触发器并仅对单元格着色。然而,这并没有做任何事情,只是在资源部分保留了上面代码中的橙色。
我只需要这个单元格 pink/light 红色而不是橙色,但我找不到包含此答案的网站或论坛文章。
带绑定的单单元格样式
在您的单元格样式中,您可以引用关联的列并识别它,例如通过比较其 Header
.
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<!-- ...other setters. -->
<Style.Triggers>
<!-- ...other triggers. -->
<DataTrigger Binding="{Binding Column.Header, RelativeSource={RelativeSource Self}}" Value="Expected Date">
<Setter Property="Background" Value="Pink" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
根据应更改颜色的状态,您可能需要使用 MultiDataTrigger
例如仅在选定状态下更改颜色。
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="True" />
<Condition Binding="{Binding Column.Header, RelativeSource={RelativeSource Self}}" Value="Expected Date" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="Pink" />
</MultiDataTrigger>
使用 Header
来标识列很麻烦并且 容易出错 。不幸的是,您可以使用的列上没有 built-in 唯一标识符。但是,您可以创建附加的 属性.
public static class DataGridColumnProperties
{
public static readonly DependencyProperty IdentifierProperty = DependencyProperty.RegisterAttached("Identifier",
typeof(string), typeof(DataGridColumnProperties), new PropertyMetadata(null));
public static string GetIdentifier(DependencyObject dependencyObject)
{
return (string)dependencyObject.GetValue(IdentifierProperty);
}
public static void SetIdentifier(DependencyObject dependencyObject, string value)
{
dependencyObject.SetValue(IdentifierProperty, value);
}
}
使用此附件 属性,您可以在您的列上设置标识符。
<DataGridTextColumn local:DataGridColumnProperties.Identifier="ExpectedDate" ...>
你可以这样引用它:
<DataTrigger Binding="{Binding Column.(local:DataGridColumnProperties.Identifier), RelativeSource={RelativeSource Self}}" Value="ExpectedDate">
<Setter Property="Background" Value="Pink" />
</DataTrigger>
这种方法使您的列定义更加健壮,因为样式独立于 Header
。
多种单元格样式
如果您更喜欢使用多种单元格样式,则无需绑定即可解决您的问题。在下文中,我在 DataGrid
中创建了所有样式,但您可以将它们移动到任何资源字典中。
在此处定义适用于大多数列的常规单元格样式RegularCellStyle
。这是您问题的风格。然后,为第一列创建一个特殊的样式,这里是 SpecialCellStyle
.
此样式使用 BasedOn
属性继承常规样式的所有设置器和触发器。在此样式中,您 仅定义与基本样式相比的变化。在您的情况下,它只是 Background
处于选中状态,因此我们为其添加一个触发器。
接下来,我们将常规样式应用到 DataGrid
s CellStyle
property. This style will be applied to all columns. Then we apply the special style to the CellStyle
of the first column. The column cell style will take precedence. From the documentation:
A Style can be applied to a cell at the table, column, or cell level. To apply a Style to all cells in a column, set the DataGridColumn.CellStyle property. This will take precedence over the DataGrid.CellStyle property. To apply a Style to an individual cell, set the Style property directly on the DataGridCell. This will take precedence over all other styles applied to the cell.
下面是您的示例的完整代码。
<DataGrid x:Name="tblopenRequests" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="2"
IsReadOnly="true" RowHeaderWidth="0" AutoGenerateColumns="False" CanUserAddRows="False" SelectionMode="Single">
<DataGrid.Resources>
<!-- Style from your question. -->
<Style x:Key="RegularCellStyle" TargetType="DataGridCell">
<Setter Property="HorizontalContentAlignment" Value="Right" />
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="Goldenrod" />
<Setter Property="BorderBrush" Value="white" />
<Setter Property="Foreground" Value="black" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontSize" Value="15" />
</Trigger>
</Style.Triggers>
</Style>
<!-- Special first column style based on the regular style. -->
<Style x:Key="SpecialCellStyle"
BasedOn="{StaticResource RegularCellStyle}"
TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="Pink" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.CellStyle>
<StaticResource ResourceKey="RegularCellStyle" />
</DataGrid.CellStyle>
<DataGrid.ColumnHeaderStyle>
<Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="LightSeaGreen" />
<Setter Property="Foreground" Value="white" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="1,1,1,1" />
<Setter Property="Margin" Value="-1,-1,0,0" />
<Setter Property="Height" Value="28" />
<Setter Property="Width" Value="auto" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding expectedDate}"
Header="Expected Date"
Width="90"
CellStyle="{StaticResource SpecialCellStyle}"/>
<!-- ...other columns WITHOUT cell style will apply the regular style. -->
</DataGrid.Columns>
</DataGrid>
感谢 @thatguy。上层帮助了我很多。值得一提的是,这是 Whosebug 和网络上使用 AutoGenerateColumns="True" 的众多答案之一。
条件颜色也可以在后面的代码中完成:
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding Column.Header, RelativeSource={RelativeSource Self}}" Value="Expected Date">
<Setter Property="Background" Value="{Binding SomeColor}" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
例如:
public SolidColorBrush SomeColor
{
get
{
return IsDifferent ? new SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 255, 139, 0)) : new SolidColorBrush(System.Windows.Media.Color.FromArgb(139, 255, 139, 0));
}
}
我有这段代码会影响 DataGrid
:
<DataGrid x:Name="tblopenRequests" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="2"
IsReadOnly="true" RowHeaderWidth="0" AutoGenerateColumns="False" CanUserAddRows="False" SelectionMode="Single">
<DataGrid.Resources>
<Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}" TargetType="{x:Type DataGridColumnHeader}" >
<Setter Property="Background" Value="LightSeaGreen" />
<Setter Property="Foreground" Value="white" />
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="1 1 1 1"/>
<Setter Property="Margin" Value="-1,-1,0,0" />
<Setter Property="Height" Value="28" />
<Setter Property="Width" Value="auto"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>
<Style TargetType="DataGridCell">
<Setter Property="HorizontalContentAlignment" Value="Right" />
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="Goldenrod" />
<Setter Property="BorderBrush" Value="white" />
<Setter Property="Foreground" Value="black" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontSize" Value="15"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
我现在想用不同的格式覆盖行中的一个单元格以更加突出。
这就是我目前的全部,但我一直在尝试失败。
<DataGridTextColumn Binding="{Binding expectedDate}" Header="Expected Date" Width="90">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
我试过在此处添加触发器并仅对单元格着色。然而,这并没有做任何事情,只是在资源部分保留了上面代码中的橙色。
我只需要这个单元格 pink/light 红色而不是橙色,但我找不到包含此答案的网站或论坛文章。
带绑定的单单元格样式
在您的单元格样式中,您可以引用关联的列并识别它,例如通过比较其 Header
.
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<!-- ...other setters. -->
<Style.Triggers>
<!-- ...other triggers. -->
<DataTrigger Binding="{Binding Column.Header, RelativeSource={RelativeSource Self}}" Value="Expected Date">
<Setter Property="Background" Value="Pink" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
根据应更改颜色的状态,您可能需要使用 MultiDataTrigger
例如仅在选定状态下更改颜色。
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="True" />
<Condition Binding="{Binding Column.Header, RelativeSource={RelativeSource Self}}" Value="Expected Date" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="Pink" />
</MultiDataTrigger>
使用 Header
来标识列很麻烦并且 容易出错 。不幸的是,您可以使用的列上没有 built-in 唯一标识符。但是,您可以创建附加的 属性.
public static class DataGridColumnProperties
{
public static readonly DependencyProperty IdentifierProperty = DependencyProperty.RegisterAttached("Identifier",
typeof(string), typeof(DataGridColumnProperties), new PropertyMetadata(null));
public static string GetIdentifier(DependencyObject dependencyObject)
{
return (string)dependencyObject.GetValue(IdentifierProperty);
}
public static void SetIdentifier(DependencyObject dependencyObject, string value)
{
dependencyObject.SetValue(IdentifierProperty, value);
}
}
使用此附件 属性,您可以在您的列上设置标识符。
<DataGridTextColumn local:DataGridColumnProperties.Identifier="ExpectedDate" ...>
你可以这样引用它:
<DataTrigger Binding="{Binding Column.(local:DataGridColumnProperties.Identifier), RelativeSource={RelativeSource Self}}" Value="ExpectedDate">
<Setter Property="Background" Value="Pink" />
</DataTrigger>
这种方法使您的列定义更加健壮,因为样式独立于 Header
。
多种单元格样式
如果您更喜欢使用多种单元格样式,则无需绑定即可解决您的问题。在下文中,我在 DataGrid
中创建了所有样式,但您可以将它们移动到任何资源字典中。
在此处定义适用于大多数列的常规单元格样式RegularCellStyle
。这是您问题的风格。然后,为第一列创建一个特殊的样式,这里是 SpecialCellStyle
.
此样式使用 BasedOn
属性继承常规样式的所有设置器和触发器。在此样式中,您 仅定义与基本样式相比的变化。在您的情况下,它只是 Background
处于选中状态,因此我们为其添加一个触发器。
接下来,我们将常规样式应用到 DataGrid
s CellStyle
property. This style will be applied to all columns. Then we apply the special style to the CellStyle
of the first column. The column cell style will take precedence. From the documentation:
A Style can be applied to a cell at the table, column, or cell level. To apply a Style to all cells in a column, set the DataGridColumn.CellStyle property. This will take precedence over the DataGrid.CellStyle property. To apply a Style to an individual cell, set the Style property directly on the DataGridCell. This will take precedence over all other styles applied to the cell.
下面是您的示例的完整代码。
<DataGrid x:Name="tblopenRequests" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="2"
IsReadOnly="true" RowHeaderWidth="0" AutoGenerateColumns="False" CanUserAddRows="False" SelectionMode="Single">
<DataGrid.Resources>
<!-- Style from your question. -->
<Style x:Key="RegularCellStyle" TargetType="DataGridCell">
<Setter Property="HorizontalContentAlignment" Value="Right" />
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="Goldenrod" />
<Setter Property="BorderBrush" Value="white" />
<Setter Property="Foreground" Value="black" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontSize" Value="15" />
</Trigger>
</Style.Triggers>
</Style>
<!-- Special first column style based on the regular style. -->
<Style x:Key="SpecialCellStyle"
BasedOn="{StaticResource RegularCellStyle}"
TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="Pink" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.CellStyle>
<StaticResource ResourceKey="RegularCellStyle" />
</DataGrid.CellStyle>
<DataGrid.ColumnHeaderStyle>
<Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="LightSeaGreen" />
<Setter Property="Foreground" Value="white" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="1,1,1,1" />
<Setter Property="Margin" Value="-1,-1,0,0" />
<Setter Property="Height" Value="28" />
<Setter Property="Width" Value="auto" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding expectedDate}"
Header="Expected Date"
Width="90"
CellStyle="{StaticResource SpecialCellStyle}"/>
<!-- ...other columns WITHOUT cell style will apply the regular style. -->
</DataGrid.Columns>
</DataGrid>
感谢 @thatguy。上层帮助了我很多。值得一提的是,这是 Whosebug 和网络上使用 AutoGenerateColumns="True" 的众多答案之一。
条件颜色也可以在后面的代码中完成:
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding Column.Header, RelativeSource={RelativeSource Self}}" Value="Expected Date">
<Setter Property="Background" Value="{Binding SomeColor}" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
例如:
public SolidColorBrush SomeColor
{
get
{
return IsDifferent ? new SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 255, 139, 0)) : new SolidColorBrush(System.Windows.Media.Color.FromArgb(139, 255, 139, 0));
}
}