在 GridView 中刷多个单元格前景

Brush multiple cells foreground within a GridView

我想在财务环境中为我的应用程序中的多个 GridView 重用一个单元格样式。这意味着所有小于 0 的单元格都应该有红色的前景色,所有大于 0 的单元格都应该是绿色,0 值应该是黑色。 所以我写了以下内容:

public class FinancialConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is decimal d)
        {
            if (d > 0)
            {
                return Brushes.Green;
            }

            if (d < 0)
            {
                return Brushes.Red;
            }
        }

        return Brushes.Black;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我现在的问题是,如何以更通用的方式应用它?

    <local:FinancialConverter x:Key="FinancialConverter" />        
    <Style TargetType="DataGridCell" x:Key="GridViewCellStyle0">
        <Setter Property="Foreground" Value="{Binding Change1Year,Converter={StaticResource FinancialConverter}}"/>
    </Style>
    <Style TargetType="DataGridCell" x:Key="GridViewCellStyle00">
        <Setter Property="Foreground" Value="{Binding Change3Year,Converter={StaticResource FinancialConverter}}"/>
    </Style>

</UserControl.Resources>

<Grid>
    <DataGrid ItemsSource="{Binding Trends}">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Change1Year,StringFormat=p}" CellStyle="{StaticResource GridViewCellStyle0}"/>
            <DataGridTextColumn Binding="{Binding Change3Year,StringFormat=p}" CellStyle="{StaticResource GridViewCellStyle00}"/>
        </DataGrid.Columns>
    </DataGrid>

我只想创建一个 GridViewCellStyle 以根据实际值进行转换。

我找到了这样的解决方案:

<DataGrid x:Name="dgvData" AutoGenerateColumns="True">
        <DataGrid.CellStyle>
            <Style TargetType="DataGridCell">
                <Setter Property="Background" Value="{Binding Content.Text,RelativeSource={RelativeSource Self}, Converter={StaticResource Conv}, Mode=OneWay}"/>
            </Style>
        </DataGrid.CellStyle>  

问题是 Content.Text 的字符串值在我的例子中是一个百分比值,我想获得基础(绑定)值。

创建自定义列类型并动态创建单元格样式:

public class FinancialTextColumn : DataGridTextColumn
{
    private static readonly FinancialConverter _converter = new FinancialConverter();

    public override BindingBase Binding
    {
        get { return base.Binding; }
        set
        {
            base.Binding = value;
            //generate the cell template:
            Binding binding = base.Binding as Binding;
            if (binding != null && binding.Path != null && !string.IsNullOrEmpty(binding.Path.Path))
                CellStyle = CreateCellStyle(binding.Path.Path);
        }
    }

    private static Style CreateCellStyle(string sourceProperty)
    {
        Style style = new Style(typeof(DataGridCell));
        style.Setters.Add(new Setter(Control.ForegroundProperty, new Binding(sourceProperty) { Converter = _converter }));
        return style;
    }
}

XAML:

<DataGrid.Columns>
    <local:FinancialTextColumn Binding="{Binding Change1Year}" />
    <local:FinancialTextColumn Binding="{Binding Change3Year}" />
</DataGrid.Columns>

您不能在纯 XAML 中执行此操作,因为除了样式的绑定路径之外,无法重用所有内容。