Для примера создадим класс Person
public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } }
Пишем небольшую заполнялку тестовых данных:
private List<Person> GenerateSampleData() { Random r = new Random(); List<Person> personList = new List<Person>(); for (int i = 1; i <= 100; i++) { personList.Add(new Person { Id = i, Name = String.Format("Person Name {0}", i), Age = r.Next(60) }); } return personList; }
Кидаем на поверхность окна DataGrid и в конструкторе формы заполняем данными:
this.dataGrid1.ItemsSource = GenerateSampleData();
И получаем вот такую милую/унылую таблицу.
Допустим, у нас стоит задача выделить цветом те “персоны”, возраст которых не достиг 16 лет.
1.1. В определение окна добавляем ссылку на пространство имен текущего проекта
xmlns:local="clr-namespace:DataGridColor"
1.2. Создаем конвертер, который будет преобразовывать возраст в кисть, которой будем закрашивать фон
class AgeToColorConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // Все проверки для краткости выкинул return (int)value <= 16 ? new SolidColorBrush(Colors.OrangeRed) : new SolidColorBrush(Colors.White); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new Exception("The method or operation is not implemented."); } }
1.3. В ресурсах окна определяем ключ конвертера
<local:AgeToColorConverter x:key="AgeToColorConverter">
1.4. И там же, в ресурсах окна, объявляем стиль, TargetType у которого будет DataGridRow.
<Style TargetType="{x:Type DataGridRow}"> <Setter Property="Background" Value="{Binding Age, Converter={StaticResource AgeToColorConverter}}" /> </Style>
В результате получаем вот такую полосатую таблицу:
А что если нужно выделять цветом не всю строку, а только отдельные ячейки в колонке. Для примера, нужно выделить ячейки с идентификатором меньше либо равно 16.
Эта задача решается похожим способом.
2.1. Добавляем в проект еще один конвертер
class IdToColorConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // Все проверки для краткости выкинул return (int)value <= 16 ? new SolidColorBrush(Colors.Yellow) : new SolidColorBrush(Colors.Green); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new Exception("The method or operation is not implemented."); } }
2.2 Присваивам ключ
<local:IdToColorConverter x:Key="IdToColorConverter" />
2.3. Добавляем в ресурсы окна еще один стиль, TargetType’ом у которого является DataGridCell. Так же стилю присваиваем ключ посредством указания x:Key="IdStyle", иначе стиль будет применен для всех ячеек во всех таблицах (а ведь нам этого не нужно).
<Style x:Key="IdStyle" TargetType="{x:Type DataGridCell}"> <Setter Property="Background" Value="{Binding Id, Converter={StaticResource IdToColorConverter}}" /> </Style>
2.4. И для колонки, в которой хотим использовать раскраску отличную от всей строки указываем CellStyle:
<DataGridTextColumn Header="ID" Width="50" Binding="{Binding Id}" CellStyle="{StaticResource IdStyle}"/>
2.5. Если раздражает, что цвет Border’a ячейки теперь берется из цвета Background’а строки, модифицируем стиль для ячейки устанавливая закраску Border’a белым цветом
<Style x:Key="IdStyle" TargetType="{x:Type DataGridCell}"> <Setter Property="Background" Value="{Binding Id, Converter={StaticResource IdToColorConverter}}" /> <Setter Property="BorderBrush" Value="White" /> </Style>
Собственно, чтобы привлечь внимание к определенной ячейке не обязательно делать из DataGrid’а приведенного попугая, достаточно подкрашивать Border присваивая BorderBrush’у акцентирующую кисть.
Если есть вопросы – задавайте, будем разбираться вместе.
UPDATE: Если нужно раскрашивать строчки в зависимости от значений нескольких полей в таблице, то следует использовать MultiBinding и реализовывать интерфейс IMultiValueConverter. Для примера реализован вариант запрошенный io, когда нужно выделить строку, если идентификатор меньше 10 или возраст меньше 16.
Пример использования MultiBinding'а:
<Style TargetType="{x:Type DataGridRow}"> <Setter Property="Background"> <Setter.Value> <MultiBinding Converter="{StaticResource MultiBindingConverter}"> <Binding Path="Id"/> <Binding Path="Age"/> </MultiBinding> </Setter.Value> </Setter> </Style>
Пример реализации IMultiValueConverter'а:
class MultiBindingConverter:IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return ((int)values[0] <10 || (int)values[1]<16) ? new SolidColorBrush(Colors.OrangeRed) : new SolidColorBrush(Colors.White); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }
PS. Выложил исходники.