如何使用 WPF Toolkit Datagrid 更改单元格的背景颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1745132/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I change the background color of a cell using WPF Toolkit Datagrid
提问by Jonathan Beerhalter
I'm using the WPF toolkit datagrid, and I'd like to set the background color of a cell, not the row, based on the content of the cell.
我正在使用 WPF 工具包数据网格,我想根据单元格的内容设置单元格的背景颜色,而不是行。
For the sake of simplicity, lets say the column is called Foo and I'd like the background of the cell to be blue when Foo is 1, red when Foo is 2, Yellow when Foo is 3 and Green when Foo is greater than 3.
为简单起见,假设该列名为 Foo,当 Foo 为 1 时,我希望单元格的背景为蓝色,当 Foo 为 2 时为红色,当 Foo 为 3 时为黄色,当 Foo 大于 3 时为绿色.
If I can do that, I'm pretty sure I can solve any of the more complex cases that I need to deal with.
如果我能做到这一点,我很确定我可以解决我需要处理的任何更复杂的案例。
回答by Ray Burns
You do this with Styles and DataTriggers. Just set your ElementStyle with your default background property, in this case Green, and add DataTriggers for the other cases:
您可以使用 Styles 和 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>
Another approach is to use a binding with a converter:
另一种方法是使用与转换器的绑定:
<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>
with this converter:
使用此转换器:
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();
}
}
Note that answer serge_gubenko gave will work as well, but only ifyour Foo property value never changes. This is because the Color property getter will only be called once. His solution can be improved by changing Color to a read-only DependencyProperty and updating it whenever Foo is assigned, but it is generally a bad idea to have UI-specific information like colors in your data model, so it is not recommended.
请注意, serge_gubenko 给出的答案也可以使用,但前提是您的 Foo 属性值永远不会改变。这是因为 Color 属性 getter 只会被调用一次。他的解决方案可以通过将 Color 更改为只读 DependencyProperty 并在分配 Foo 时更新它来改进,但是在数据模型中包含特定于 UI 的信息(如颜色)通常是一个坏主意,因此不建议这样做。
回答by serge_gubenko
One of the ways how you could do this is to define the ElementStyle for the column and then bind the textblock background to the color property of the data element behind the datagrid row. Here's an example:
执行此操作的方法之一是为列定义 ElementStyle,然后将文本块背景绑定到数据网格行后面的数据元素的颜色属性。下面是一个例子:
DataGridTextColumn xaml:
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>
data item declaration:
数据项声明:
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);
}
}
}
hope this helps, regards
希望这有帮助,问候
回答by Samuel
The serge_gubenko will work well if your item inherits From INotifyPropertyChanged then when your property will change call to NotifyPropertyChanged("yourproperty")
如果您的项目继承自 INotifyPropertyChanged,则 serge_gubenko 将正常工作,然后当您的财产将更改调用 NotifyPropertyChanged("yourproperty")
回答by CptCoathanger
A slightly different approaching is, instead of targeting the TextBlock
element, which often leaves a border around the control, to the DataGridCell
itself instead. In my case I already had a style I wanted to inherit from, I just needed to change background colours depending on the value:
一个稍微不同的方法是,不是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>
Might be of some use to people my situation.
可能对我的情况有所帮助。