Как изменить цвет фона ячейки с помощью WPF Toolkit Datagrid
Я использую сетку данных инструментария WPF и хочу установить цвет фона ячейки, а не строки, основываясь на содержимом ячейки.
Для простоты предположим, что столбец называется Foo, и я хотел бы, чтобы фон ячейки был синим, когда Foo равен 1, красным, если Foo равен 2, желтым, если Foo равно 3, и зеленым, если Foo больше 3,
Если я смогу это сделать, я почти уверен, что смогу решить любой из более сложных случаев, с которыми мне нужно иметь дело.
3 ответа
Вы делаете это с помощью стилей и DataTriggers. Просто установите свой ElementStyle с свойством фона по умолчанию, в данном случае Green, и добавьте DataTriggers для других случаев:
<DataGridTextColumn Binding="{Binding WhateverIWantToDisplay}" >
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="Green" />
<Style.Triggers>
<DataTrigger Binding="{Binding Foo}" Value="1">
<Setter Property="Background" Value="Blue" />
</DataTrigger>
<DataTrigger Binding="{Binding Foo}" Value="2">
<Setter Property="Background" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding Foo}" Value="2">
<Setter Property="Background" Value="Yellow" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
Другой подход заключается в использовании привязки с конвертером:
<DataGridTextColumn Binding="{Binding WhateverIWantToDisplay}" >
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background"
Value="{Binding Foo, Converter={x:Static my:FooToColorConverter.Instance}}" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
с этим конвертером:
public class FooToColorConverter : IValueConverter
{
public static readonly IValueConverter Instance = new FooToColorConverter();
public object Convert(object value, ...
{
int foo = (int)value;
return
foo==1 ? Brushes.Blue :
foo==2 ? Brushes.Red :
foo==3 ? Brushes.Yellow :
foo>3 ? Brushes.Green :
Brushes.Transparent; // For foo<1
}
public object ConvertBack(...
{
throw new NotImplementedException();
}
}
Обратите внимание, что ответ, который дал serge_gubenko, также будет работать, но только если значение вашего свойства Foo никогда не изменится. Это связано с тем, что метод получения свойства Color будет вызываться только один раз. Его решение можно улучшить, изменив Color на DependencyProperty, доступный только для чтения, и обновляя его всякий раз, когда назначается Foo, но, как правило, плохая идея иметь информацию о пользовательском интерфейсе, такую как цвета, в вашей модели данных, поэтому это не рекомендуется.
Один из способов сделать это - определить ElementStyle для столбца, а затем связать фон текстового блока со свойством color элемента данных за строкой сетки данных. Вот пример:
DataGridTextColumn xaml:
<DataGridTextColumn Width="SizeToCells"
MinWidth="150"
Binding="{Binding Name}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextBlock.Background" Value="{Binding Color}" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
объявление элемента данных:
public class TestItem
{
public TestItem(int foo)
{
Foo = foo;
}
public int Foo { get; set; }
public Brush Color
{
get
{
Color color = Colors.Green;
switch (Foo)
{
case 1: color = Colors.Red; break;
case 2: color = Colors.Yellow; break;
}
return new SolidColorBrush(color);
}
}
}
надеюсь, что это помогает, привет
Несколько иной подход - вместо того, чтобы нацеливаться на TextBlock
элемент, который часто оставляет границу вокруг элемента управления, к DataGridCell
вместо этого. В моем случае у меня уже был стиль, который я хотел унаследовать, мне просто нужно было изменить цвета фона в зависимости от значения:
<DataGridTextColumn
Width="*"
Header="Status"
Binding="{Binding EventStatus, Converter={StaticResource DescriptionAttributeConverter}}"
HeaderStyle="{StaticResource DataGridColumnHeaderStyleCenterAligned}">
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource DataGridCellStyleCenterAligned}">
<Style.Triggers>
<DataTrigger Binding="{Binding EventStatus}" Value="1">
<Setter Property="Background" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding EventStatus}" Value="2">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
Может быть, мне пригодится моя ситуация.
Serge_gubenko будет работать хорошо, если ваш элемент наследует от INotifyPropertyChanged тогда, когда ваше свойство изменит вызов на NotifyPropertyChanged("yourproperty")