This is a quite nasty problem, which I had to solve some time ago.
I used the following code:
Basically: You need a Valueconverter o get the Value of the row / cell simulatneously.
In the example here I used a Multivalueconverter because I needed information about the Colzumn, too - depending on your scenerio, a normal Value-Converter would be enough.
XAML
//for the convers
<DataGrid x:Name="bla">
// use this column if you want to style the header too
<DataGrid.RowHeaderStyle>
<Style TargetType="DataGridRowHeader">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type DataGridRow}},
Converter={StaticResource ExcelRowColorConverter}}">
</Setter>
<Setter Property="BorderThickness" Value="1,0,1,1"></Setter>
<Setter Property="BorderBrush" Value="#FF000000"></Setter>
</Style>
</DataGrid.RowHeaderStyle>
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="DataGrid.Background">
<Setter.Value>
<MultiBinding Converter="{StaticResource ExcelDataGridCellColorConverter}" >
<MultiBinding.Bindings>
// this is the critical piece to style a particular cell
the C#-Code
//-----------------------------------------------------------------------
// <copyright file="ExcelDataGridCellColorConverter.cs" company="best Research">
// Copyright (c) best Research. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace myTool.Utils
{
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
/// <summary>
/// Used to convert a cell to its final color. It determines this based on both row and column.
/// </summary>
public class ExcelDataGridCellColorConverter : IMultiValueConverter
{
/// <summary>
/// Used to convert a cell to its final color. It determines this based on both row and column.
/// </summary>
/// <param name="values">the parameter array</param>
/// <param name="targetType">The target type.</param>
/// <param name="parameter">the parameter.</param>
/// <param name="culture">the culture.</param>
/// <returns>
/// A Brush
/// </returns>
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values[1] is DataRow)
{
var cell = (DataGridCell)values[0];
var row = (DataRow)values[1];
var columnName = cell.Column.SortMemberPath;
var table = row.Table;
// this is used because there is a bug in WPF which causes a removed datarow to be "seen". This happens when deleting empty rows. The Key "lock" should be added by the deleting method and then removed afterwards.
if (table.ExtendedProperties.Contains("lock"))
{
return Brushes.Gainsboro;
}
var colValue = table.Rows[table.Rows.Count - 1][columnName];
var rowValue = row[Properties.Resources.ColorColumnName];
var colorColValue = (Enums.RowState)Enum.Parse(typeof(Enums.RowState), colValue.ToString(), true);
var colorRowValue = (Enums.RowState)Enum.Parse(typeof(Enums.RowState), rowValue.ToString(), true);
if (colorColValue == Enums.RowState.IsIncluded && colorRowValue == Enums.RowState.IsIncluded)
{
return Brushes.LightGreen;
}
else if (colorRowValue == Enums.RowState.HeaderRow)
{
return Brushes.Gainsboro;
}
else
{
return Brushes.LightSalmon;
}
}
return Brushes.Blue;
}
/// <summary>
/// Not used
/// </summary>
/// <param name="value">the parameter</param>
/// <param name="targetTypes">The target types.</param>
/// <param name="parameter">the parameter.</param>
/// <param name="culture">the culture.</param>
/// <returns>
/// A Brush
/// </returns>
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
}