Как изменить цвет фона ячейки с помощью WPF Toolkit Datagrid - PullRequest
22 голосов
/ 17 ноября 2009

Я использую сетку данных инструментария WPF и хочу установить цвет фона ячейки, а не строки, основываясь на содержимом ячейки.

Для простоты, скажем, столбец называется Foo, и я хотел бы, чтобы фон ячейки был синим, когда Foo равен 1, красным, когда Foo равен 2, желтым, если Foo равен 3, и зеленым, если Foo равен больше 3.

Если я смогу это сделать, я почти уверен, что смогу решить любой из более сложных случаев, с которыми мне нужно иметь дело.

Ответы [ 4 ]

35 голосов
/ 17 ноября 2009

Вы делаете это с помощью стилей и 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>

Другой подход заключается в использовании привязки с конвертером:

<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 будет вызываться только один раз. Его решение можно улучшить, изменив Color на DependencyProperty, доступный только для чтения, и обновляя его всякий раз, когда назначается Foo, но в целом плохая идея иметь информацию о пользовательском интерфейсе, такую ​​как цвета, в модели данных, поэтому это не рекомендуется. *

6 голосов
/ 17 ноября 2009

Один из способов сделать это - определить ElementStyle для столбца, а затем привязать фон текстового блока к свойству color элемента данных за строкой сетки данных. Вот пример:

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

надеюсь, это поможет, с уважением

1 голос
/ 12 апреля 2012

serge_gubenko будет хорошо работать, если ваш элемент наследует от INotifyPropertyChanged, а затем, когда ваше свойство изменит вызов, на NotifyPropertyChanged ("yourproperty")

0 голосов
/ 13 июня 2019

Немного другой подход - вместо нацеливания на элемент 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>

Может пригодиться людям в моей ситуации.

...