web-dev-qa-db-ja.com

WPF ToolkitDatagridを使用してセルの背景色を変更するにはどうすればよいですか

WPFツールキットデータグリッドを使用していますが、セルの内容に基づいて、行ではなくセルの背景色を設定したいと思います。

簡単にするために、列をFooと呼び、セルの背景をFooが1の場合は青、Fooが2の場合は赤、Fooが3の場合は黄色、Fooが3より大きい場合は緑にします。 。

それができれば、対処する必要のあるより複雑なケースを解決できると確信しています。

23

これは、StylesとDataTriggersを使用して行います。 ElementStyleをデフォルトのbackgroundプロパティ(この場合は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プロパティゲッターが1回だけ呼び出されるためです。彼のソリューションは、Colorを読み取り専用のDependencyPropertyに変更し、Fooが割り当てられるたびに更新することで改善できますが、データモデルに色などのUI固有の情報を含めることは一般に悪い考えであるため、お勧めしません。

40
Ray Burns

これを行う方法の1つは、列の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);
        }
    }
}

これがお役に立てば幸いです

6
serge_gubenko

Serge_gubenkoは、アイテムがFrom INotifyPropertyChangedを継承し、プロパティが変更されるときにNotifyPropertyChanged( "yourproperty")への呼び出しが適切に機能します。

1
Samuel

少し異なるアプローチは、コントロールの周囲に境界線を残すことが多い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>

私の状況の人々にいくらか役立つかもしれません。

1
CptCoathanger