我有一个数据网格,它是一个金融计算器,其中一些单元格在负值上变为红色。这是通过带转换器的DataTrigger完成的。我也覆盖了系统高亮选择颜色。我现在的问题是,当我选择一行时,红色单元格不会突出显示。
据我所知,自定义单元格样式会覆盖选择。我希望我的自定义红色单元格也用0.5不透明蓝色条突出显示。我该如何解决这个问题?
好吧,我可以为细胞样式添加一个额外的触发器,在选择时改变BG颜色并调整颜色以适应,但这相当于一个kludge。或者也许我可以在某种程度上实现不透明度的叠加颜色?
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="LightBlue" />
</Trigger>
以下是完整代码。这是一个精简,重量轻但功能齐全的例子。
XAML
<Window.Resources>
<local:ValueToBoolConverter x:Key="ValueToBoolConverter"/>
</Window.Resources>
<Grid>
<DataGrid ItemsSource="{Binding MainTable}"
AutoGenerateColumns="False"
CanUserAddRows="False">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Background" Value="Azure"/>
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Blue" Opacity="0.5" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Transparent" />
</Style.Resources>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Income Day" Binding="{Binding IncomeDay}" />
<DataGridTextColumn Header="Income Week" Binding="{Binding IncomeWeek}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding IncomeWeek, Converter={StaticResource ValueToBoolConverter}}" Value="true">
<Setter Property="Background" Value="Salmon"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Income Month" Binding="{Binding IncomeMonth}" />
<DataGridTextColumn Header="Income Year" Binding="{Binding IncomeYear}" Width="*" />
</DataGrid.Columns>
</DataGrid>
</Grid>
C#
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace Datagrid_Cell_Highlight
{
public class TableData
{
public decimal IncomeDay { get; set; }
public decimal IncomeWeek { get; set; }
public decimal IncomeMonth { get; set; }
public decimal IncomeYear { get; set; }
}
public class ViewModel
{
public ObservableCollection<TableData> MainTable { get; set; }
public ViewModel()
{
MainTable = new ObservableCollection<TableData>
{
new TableData { IncomeDay = (decimal)1.11 },
new TableData { IncomeDay = (decimal)2.22 },
new TableData { IncomeDay = (decimal)-1.23 },
new TableData { IncomeDay = (decimal)-2.34 }
};
foreach (var table in MainTable)
{
table.IncomeWeek = table.IncomeDay * 7;
table.IncomeMonth = table.IncomeDay * 30;
table.IncomeYear = table.IncomeDay * 365;
}
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
public class ValueToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if ((value is decimal) && ((decimal)value < 0))
return true;
else return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
答案 0 :(得分:0)
“Kludge”与否,单元格的Background
确实会“覆盖”该行的背景,因此您应该将另一个触发器添加到考虑到这一点的单元格样式中。例如,您可以使用包含红色和蓝色画笔的MultiDataTrigger
和DrawingBrush
:
<DataGridTextColumn Header="Income Week" Binding="{Binding IncomeWeek}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding IncomeWeek, Converter={StaticResource ValueToBoolConverter}}" Value="true">
<Setter Property="Background" Value="Salmon"/>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IncomeWeek, Converter={StaticResource ValueToBoolConverter}}" Value="true" />
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Background">
<Setter.Value>
<DrawingBrush Viewport="0,0,1,1" TileMode="Tile">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,1,1" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<SolidColorBrush Color="Salmon"/>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,1,1" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<SolidColorBrush Color="Blue" Opacity="0.2"/>
</GeometryDrawing.Brush>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Setter.Value>
</Setter>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
答案 1 :(得分:0)
您可以使用MultiDataTrigger实现此目的。但是你为什么认为这是一个&#34; kludge&#34;?我觉得它很优雅。
mm8代码的替代方法是简单地设置两个MultiDataTriggers。 IsSelected为false时触发的第一个为Is,而IsSelected为true时触发的第二个方式。
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="False"/>
<Condition Binding="{Binding IncomeWeek, Converter={StaticResource ValueToBoolConverter}}" Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Background" Value="Salmon"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True"/>
<Condition Binding="{Binding IncomeWeek, Converter={StaticResource ValueToBoolConverter}}" Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="BorderThickness" Value="0"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>