🗿

[WPF/C#] ListViewの行の背景色を、データの中身によって変える

2021/07/31に公開

もくじ

https://qiita.com/tera1707/items/4fda73d86eded283ec4f

やりたいこと

WPFでListViewを使うときに、その行のデータによって、行の背景色を変えたい。

例えば、下図のように、Nameが「Green」の行だけ、その行の背景色をGreenにする、というようなこと。

やり方

ListViewの<ListView.ItemContainerStyle>に、DataTriggerを入れたstyleを仕込んでやる。

試したコード

画面xaml

<ListView.ItemContainerStyle>のところに、

  • Nameが「Green」だったら、
    • BorderBrush を Green にする
    • Background を Green にする

というのを入れている。

MainWindow.xaml
<Window x:Class="ListViewTet.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ListViewTet"
        mc:Ignorable="d"
        Title="MainWindow" Height="200" Width="300">
    <Grid>
        <ListView ItemsSource="{Binding DataList}">
            <ListView.ItemContainerStyle>
                <Style TargetType="{x:Type ListViewItem}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Name}" Value="Green">
                            <Setter Property="BorderBrush" Value="Green"/>
                            <Setter Property="Background" Value="Green"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="No"  DisplayMemberBinding="{Binding No}" Width="30"/>
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="100"/>
                    <GridViewColumn Header="Brush" DisplayMemberBinding="{Binding Brush}" Width="100"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

コードビハインド

実験用データを仕込んでるだけ。

MainWindow.xaml.cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Media;

namespace ListViewTet
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName) => this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        #endregion

        public ObservableCollection<MyData> DataList { get; set; } = new ObservableCollection<MyData>();

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;

            DataList.Add(new MyData() { No = 1, Brush = new SolidColorBrush(Colors.Red), Name = "Red" });
            DataList.Add(new MyData() { No = 2, Brush = new SolidColorBrush(Colors.Blue), Name = "Blue" });
            DataList.Add(new MyData() { No = 3, Brush = new SolidColorBrush(Colors.Green), Name = "Green" });
            DataList.Add(new MyData() { No = 4, Brush = new SolidColorBrush(Colors.Yellow), Name = "Yellow" });
            DataList.Add(new MyData() { No = 5, Brush = new SolidColorBrush(Colors.Green), Name = "Green" });
        }
    }

    public class MyData
    {
        public int No { get; set; }
        public SolidColorBrush Brush { get; set; }
        public string Name { get; set; }
    }
}

備考

下記の記事で試した、標準?のListViewのstyleを使ってまるっと見た目を好きなようにするときも、上の<ListView.ItemContainerStyle>の内容をDictionaryのxamlに入れてやればいいかも。(未検証)

https://zenn.dev/tera1707/articles/c1331f8559f05e

Discussion