English 中文(简体)
How do I change the background color of a cell using WPF Toolkit Datagrid
原标题:

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.

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.

If I can do that, I m pretty sure I can solve any of the more complex cases that I need to deal with.

最佳回答

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:

<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.

问题回答

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:

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

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:

<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.

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





相关问题
WPF convert 2d mouse click into 3d space

I have several geometry meshes in my Viewport3D, these have bounds of (w:1800, h:500, d:25). When a user clicks in the middle of the mesh, I want the Point3D of (900, 500, 25)... How can I achieve ...

Editing a xaml icons or images

Is it possible to edit a xaml icons or images in the expression design or using other tools? Is it possible to import a xaml images (that e.g you have exported) in the expression designer for editing?...

WPF: writing smoke tests using ViewModels

I am considering to write smoke tests for our WPF application. The question that I am faced is: should we use UI automation( or some other technology that creates a UI script), or is it good enough to ...

WPF - MVVM - NHibernate Validation

Im facing a bit of an issue when trying to validate a decimal property on domain object which is bound to a textbox on the view through the viewmodel. I am using NHibernate to decorate my property on ...

How do WPF Markup Extensions raise compile errors?

Certain markup extensions raise compile errors. For example StaticExtension (x:Static) raises a compile error if the referenced class cannot be found. Anyone know the mechanism for this? Is it baked ...

WPF design-time context menu

I am trying to create a custom wpf control, I m wondering how I can add some design-time features. I ve googled and can t seem to get to my goal. So here s my simple question, how can I add an entry ...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签