You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF DataGrid多字段判断单元格背景色设置方案求助

WPF DataGrid多字段条件设置单元格背景

场景与需求

开发C# WPF应用,现有DataGrid包含Vlarema、PFas、RiskCat列,需求为:当RiskCat值为2或3,且Vlarema单元格(日期类型)早于1年,或无日期时,将该单元格背景设为红色警告。目前用IValueConverter仅能处理单个值,无法同时获取RiskCat判断,尝试IMultiValueConverter但不确定实现方式。

现有代码

XAML部分

<DataGrid x:Name="ProductLijstDatagrid"  MaxWidth="1700" Style="{StaticResource CustomDataGridStyle}" Grid.Row="13" Grid.ColumnSpan="5" Margin="15,0,15,0"  MaxHeight="350">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Vlarema" Binding="{Binding Vlarema}">
            <DataGridTextColumn.ElementStyle>
                <Style TargetType="{x:Type TextBlock}">
                    <Setter Property="Background" Value="{Binding Vlarema, Converter={StaticResource VlaremaBrushConverter}}"/>
                </Style>
            </DataGridTextColumn.ElementStyle>
        </DataGridTextColumn>
        <DataGridTextColumn Header="PFas" Binding="{Binding PFas}"/>
        <DataGridTextColumn Header="RiskCat" Binding="{Binding RiskCat}"/>
    </DataGrid.Columns>
</DataGrid>

C#转换器代码

public class VlaremaBrushConverter : IValueConverter
{
    RisicocategorieConverter rc = new RisicocategorieConverter();
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string riskCat = "";
        string input = (string)value;
        switch (input)
        {
            case "00/00/0000": return Brushes.Red;              
            default: return DependencyProperty.UnsetValue;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

public class RiskCatConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Length > 0 && values[0] is int risicocategorie)
        {
            if (risicocategorie == 2 || risicocategorie == 3)
            {
                return risicocategorie;
            }
        }

        return false;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    public int GetRisicoCategorie(DataGridCell cell)
    {
        if (cell.Content is TextBlock textBlock && textBlock.GetBindingExpression(TextBlock.TextProperty) is BindingExpression bindingExpression)
        {
            var dataRow = bindingExpression.DataItem as DataRowView;
            if (dataRow != null && dataRow.Row.Table.Columns.Contains("Risicocategorie"))
            {
                int risicocategorie = (int)dataRow["Risicocategorie"];
                return risicocategorie;
            }
        }
        return 0;
    }
}

解决方案:用IMultiValueConverter实现多字段判断

直接实现一个能同时接收Vlarema和RiskCat的多值转换器,再修改XAML中的绑定方式即可。

1. 实现正确的IMultiValueConverter

public class VlaremaWarningConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        // 确保传入两个有效参数
        if (values.Length != 2)
            return DependencyProperty.UnsetValue;

        // 验证RiskCat类型与值
        if (!(values[1] is int riskCat) || (riskCat != 2 && riskCat != 3))
            return DependencyProperty.UnsetValue;

        // 处理Vlarema的情况
        string vlaremaStr = values[0] as string;
        // 无日期的情况
        if (string.IsNullOrEmpty(vlaremaStr) || vlaremaStr == "00/00/0000")
            return Brushes.Red;

        // 解析日期并判断是否早于1年前
        if (DateTime.TryParse(vlaremaStr, out DateTime vlaremaDate) 
            && vlaremaDate < DateTime.Now.AddYears(-1))
        {
            return Brushes.Red;
        }

        // 不符合条件,使用默认背景
        return DependencyProperty.UnsetValue;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

2. 修改XAML绑定

将原来的单个Binding替换为MultiBinding,同时绑定Vlarema和RiskCat两个字段:

<DataGridTextColumn Header="Vlarema" Binding="{Binding Vlarema}">
    <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Background">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource VlaremaWarningConverter}">
                        <Binding Path="Vlarema"/>
                        <Binding Path="RiskCat"/>
                    </MultiBinding>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

3. 声明转换器资源

在Window或UserControl的Resources中添加转换器声明(注意替换local为你的项目命名空间):

<Window.Resources>
    <local:VlaremaWarningConverter x:Key="VlaremaWarningConverter"/>
</Window.Resources>

逻辑说明

转换器先判断RiskCat是否为2或3,不符合则直接返回默认背景;符合条件后再检查Vlarema:如果是无日期(空或"00/00/0000"),或者解析后的日期早于当前日期1年以上,就返回红色背景,否则使用默认样式。

内容的提问来源于stack exchange,提问作者UwUs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 12:53:08