如何使用 WPF Toolkit Datagrid 更改单元格的背景颜色

Posted

技术标签:

【中文标题】如何使用 WPF Toolkit Datagrid 更改单元格的背景颜色【英文标题】:How do I change the background color of a cell using WPF Toolkit Datagrid 【发布时间】:2010-12-17 05:43:01 【问题描述】:

我正在使用 WPF 工具包数据网格,我想根据单元格的内容设置单元格的背景颜色,而不是行的背景颜色。

为了简单起见,假设列名为 Foo,我希望单元格的背景在 Foo 为 1 时为蓝色,在 Foo 为 2 时为红色,在 Foo 为 3 时为黄色,当 Foo 为绿色时大于 3。

如果我能做到这一点,我很确定我可以解决我需要处理的任何更复杂的案例。

【问题讨论】:

【参考方案1】:

执行此操作的方法之一是为列定义 ElementStyle,然后将文本块背景绑定到数据网格行后面的数据元素的颜色属性。这是一个例子:

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);
        
    

希望这会有所帮助,问候

【讨论】:

如果 Foo 的值在网格显示后发生变化,这将不起作用:单元格颜色不会更新。有关详细信息,请参阅我的答案。 在显示网格时,如果 Foo 发生变化(例如,由于数据绑定),也不会发生变化。 它已经很老了,但你需要修复它是通过类 TestItem 实现 INotifyPropertyChanged,以通知 UI 颜色变化。【参考方案2】:

您可以使用样式和数据触发器来执行此操作。只需使用默认背景属性设置 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 的信息(如颜色)通常是一个坏主意,因此不建议这样做。

【讨论】:

非常感谢。我发现 WPF 使用起来非常令人沮丧,因为它往往会隐藏错误,并且当您没有正确的代码时不会做任何事情。但是当它工作时,当您知道自己在做什么时,它的闪电般快速且易于使用。老实说,在我使用过的所有技术中,WPF 的学习曲线是最陡峭的。无论如何,再次感谢。我选择了转换器,因为它给了我最大的灵活性。【参考方案3】:

如果您的项目从 INotifyPropertyChanged 继承,那么 serge_gubenko 将运行良好,然后您的属性将更改调用 NotifyPropertyChanged("yourproperty")

【讨论】:

【参考方案4】:

一种稍微不同的方法是,而不是将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>

可能对我的情况有用。

【讨论】:

以上是关于如何使用 WPF Toolkit Datagrid 更改单元格的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

WPF Toolkit Datagrid - 如何关闭选择?

.NET 4 WPF Datagrid 和 WPF Toolkit Datagrid 之间的差异

WPF Toolkit DataGrid 列调整大小事件

WPF DataGrid 每行ComboBox 内容不同的设置方法

wpf datagrid过滤器列标题值访问

WPF MvvM DataGrid 动态列