我正在使用WPF工具包数据网格,并且我想基于单元格的内容而不是行设置单元格的背景颜色。
为了简单起见,假设列名为Foo,当Foo为1时,我想将单元格的背景设置为蓝色,当Foo为2时为红色,当Foo为3时为黄色,当Foo大于3时为绿色。
如果我能做到这一点,我相信我能解决任何更复杂的情况。
我正在使用WPF工具包数据网格,并且我想基于单元格的内容而不是行设置单元格的背景颜色。
为了简单起见,假设列名为Foo,当Foo为1时,我想将单元格的背景设置为蓝色,当Foo为2时为红色,当Foo为3时为黄色,当Foo大于3时为绿色。
如果我能做到这一点,我相信我能解决任何更复杂的情况。
您可以使用样式和数据触发器来实现此操作。只需使用默认背景属性(在本例中为绿色)设置ElementStyle,并为其他情况添加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属性的getter方法只会被调用一次。可以通过将Color更改为只读DependencyProperty并在分配Foo时更新它来改进他的解决方案,但通常在数据模型中拥有UI特定信息(如颜色)是一个坏习惯,因此不建议这样做。您可以通过定义列的ElementStyle并将textblock背景绑定到数据元素的颜色属性来实现此目的。以下是一个例子:
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>
如果你的项目从INotifyPropertyChanged继承,那么serge_gubenko将会很好用,当你的属性改变时,调用NotifyPropertyChanged("yourproperty")。