WPF 数据网格.无法突出显示自定义样式的单元格



我有一个数据网格,它是一个财务计算器,其中一些单元格在负值时变为红色。这是通过带转换器的数据触发器完成的。我还覆盖了系统突出显示选择颜色。我现在的问题是,当我选择一行时,红色单元格不会突出显示。

这是图片

据我了解,自定义单元格样式会覆盖选择。我希望我的自定义红色单元格也用 0.5 不透明度的蓝色条突出显示。我该如何解决这个问题?

好吧,我可以在单元格样式中添加一个额外的触发器,在选择时更改 BG 颜色并调整颜色以适应,但这相当麻烦。或者,也许我可以以某种方式在这里实现不透明度的叠加颜色?

<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();
        }
    }
}

"Kludge"与否,单元格的Background确实会"覆盖"行的背景,因此您应该在单元格样式中添加另一个触发器,以考虑到这一点。例如,您可以使用同时包含红色和蓝色画笔的MultiDataTriggerDrawingBrush

<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>

您可以使用MultiDataTrigger来实现此目的。但是为什么你认为这是一个"笨蛋"?我认为它相当优雅。

mm8代码的替代方案是简单地设置两个多数据触发器。当 IsSelected 为假时触发的第一种方式,当 IsSelected 为真时触发的第一种方式。

<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>

相关内容

  • 没有找到相关文章

最新更新