Q096. DataGrid でセルの値を変えると背景色が変わるようにするには?

A.DataGridColumn.CellStyle にスタイルを定義し、トリガーを設定します。



以下は、Livet を使ったサンプルです。
まず Model に Person クラスを用意しました。名前と所属と住所だけの簡単なクラスです。ちなみに名前空間はコードの都合上、省略してますのでご注意ください。

public class Person {
    public string Name { get; set; }
    public string Post { get; set; }
    public string Address { get; set; }
}


次は Person のコレクションを生成するファクトリクラスを用意します。コレクションは ObservableCollection を使います。WPF の場合、コレクションは ObservableCollection を使うのが定番ですね。

using System.Collections.ObjectModel;

static class Persons {
    public static ObservableCollection<Person> Create() {
        var collection = new ObservableCollection<Person>();
        collection.Add(new Person() { 
            Name = "田中次郎", Post = "営業", Address = "東京都新宿区"
        });
        collection.Add(new Person() { 
            Name = "山田太郎", Post = "販売", Address = "東京都大田区"
        });
        collection.Add(new Person() { 
            Name = "鈴木花子", Post = "総務", Address = "神奈川県川崎市"
        });
        return collection;
    }     
}


お次は ViewModel と ComboBox のソースを用意します。

using System.Collections.Generic;
using System.Collections.ObjectModel;
using Livet;

// ViewModel
public class MainWindowViewModel : ViewModel {
    public void Initialize() {
        this.Persons = LivetWPFApplication1.Models.Persons.Create();
    }

    #region Persons変更通知プロパティ
    private ObservableCollection<Person> _Persons;

    public ObservableCollection<Person> Persons {
        get { return _Persons; }
        set { 
            if (_Persons == value)
                return;
            _Persons = value;
            RaisePropertyChanged("Persons");
        }
    }
    #endregion
}

// ComboBox のソース
public class PostList : List<string> {
    public PostList() {
        this.Add("総務");
        this.Add("営業");
        this.Add("販売");
        this.Add("製造");
    }
}


最後は View。所属セルの値をコンボボックスで変更し、セルからフォーカスを外せばただちに色が変わります。

<Window x:Class="LivetWPFApplication1.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
    xmlns:v="clr-namespace:LivetWPFApplication1.Views"
    xmlns:vm="clr-namespace:LivetWPFApplication1.ViewModels"
    Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <!-- コンボボックスのソースをリソースとして用意 -->
    <vm:PostList x:Key="PostList" />
  </Window.Resources>
  <Window.DataContext>
    <vm:MainWindowViewModel/>
  </Window.DataContext>
  
  <i:Interaction.Triggers>
    <!--WindowのContentRenderedイベントのタイミングでViewModelのInitializeメソッドが呼ばれます-->
    <i:EventTrigger EventName="ContentRendered">
      <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="Initialize"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
  
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="60"/>
      <RowDefinition />
    </Grid.RowDefinitions>
    <DataGrid Grid.Row="1"  AutoGenerateColumns="False" 
          Name="dataGrid1" ItemsSource="{Binding Persons}" >
      <DataGrid.Columns>
        <DataGridTextColumn Header="名前" Width="120" Binding="{Binding Name}" />
        <DataGridComboBoxColumn Header="所属" Width="120" 
                    ItemsSource="{StaticResource PostList}"
                    SelectedItemBinding="{Binding Post, UpdateSourceTrigger=PropertyChanged}" >
          <!-- 所属により前景色と背景色が変わるよう、トリガーを設定する -->
          <DataGridComboBoxColumn.CellStyle>
            <Style TargetType="{x:Type DataGridCell}" >
              <Style.Triggers>
                <DataTrigger Binding="{Binding Post}" Value="営業" >
                  <Setter Property="Background" Value="Black" />
                  <Setter Property="Foreground" Value="White" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Post}" Value="総務" >
                  <Setter Property="Background" Value="Coral" />
                  <Setter Property="Foreground" Value="White" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Post}" Value="販売" >
                  <Setter Property="Background" Value="DarkKhaki" />
                  <Setter Property="Foreground" Value="Red" />
                </DataTrigger>
              </Style.Triggers>
            </Style>
          </DataGridComboBoxColumn.CellStyle>
        </DataGridComboBoxColumn>
        <DataGridTextColumn Header="住所" Width="*" Binding="{Binding Address}" />
      </DataGrid.Columns>
    </DataGrid>
  </Grid>
</Window>

WPF FAQ の目次に戻る