如何使用WPF工具箱Datagrid更改单元格的背景色

时间:2021-09-01 22:19:10

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 toolkit datagrid,我想根据单元格的内容设置单元格的背景颜色,而不是行。

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.

如果我能做到这一点,我很肯定我能解决任何更复杂的情况。

3 个解决方案

#1


33  

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:

您可以使用样式和数据处理程序进行此操作。只需将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>

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 if your 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属性值永不改变。这是因为颜色属性getter只会被调用一次。可以通过将颜色更改为只读的DependencyProperty并在分配Foo时更新它来改进他的解决方案,但是在数据模型中包含特定于ui的信息(如颜色)通常不是一个好主意,所以不推荐使用它。

#2


6  

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,然后将textblock背景绑定到datagrid行后面的数据元素的颜色属性。这里有一个例子:

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

希望这有助于,问候

#3


1  

The serge_gubenko will work well if your item inherits From INotifyPropertyChanged then when your property will change call to NotifyPropertyChanged("yourproperty")

如果您的项目继承inotifypropertytychanged,那么当您的属性将调用NotifyPropertyChanged(“您的属性”)时,serge_gubenko将工作得很好

#1


33  

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:

您可以使用样式和数据处理程序进行此操作。只需将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>

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 if your 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属性值永不改变。这是因为颜色属性getter只会被调用一次。可以通过将颜色更改为只读的DependencyProperty并在分配Foo时更新它来改进他的解决方案,但是在数据模型中包含特定于ui的信息(如颜色)通常不是一个好主意,所以不推荐使用它。

#2


6  

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,然后将textblock背景绑定到datagrid行后面的数据元素的颜色属性。这里有一个例子:

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

希望这有助于,问候

#3


1  

The serge_gubenko will work well if your item inherits From INotifyPropertyChanged then when your property will change call to NotifyPropertyChanged("yourproperty")

如果您的项目继承inotifypropertytychanged,那么当您的属性将调用NotifyPropertyChanged(“您的属性”)时,serge_gubenko将工作得很好