[WPF/xaml] ListViewのGrid表示のセルの中身をカスタムする

# もくじ

https://tera1707.com/entry/2022/02/06/144447

# やりたいこと

GridのListView表示の、セルの中を好きなようにいじりたい。
下記のようなイメージ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/f879ee49-b88b-ec3d-7a07-d7b71beba3c4.png)

# やりかた

`<GridViewColumn.CellTemplate>`を使う。

# サンプル

```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="450" Width="800">
    <Grid>
        <ListView ItemsSource="{Binding DataList}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="色" DisplayMemberBinding="{Binding No}" Width="80" />
                    <GridViewColumn Header="コード" Width="80" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding Brush}" />
                                    <Rectangle Fill="{Binding Brush}" Width="10" Height="10"/>
                                </StackPanel>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </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) });
            DataList.Add(new MyData() { No = 2, Brush = new SolidColorBrush(Colors.Blue) });
            DataList.Add(new MyData() { No = 3, Brush = new SolidColorBrush(Colors.Green) });
        }
    }

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

# 注意

下記のページで勉強させていただいた内容。

http://var.blog.jp/archives/67281536.html

### DisplayMemberBindingとCellTemplate

`<GridViewColumn >`に、ListViewのItemsTemplateにバインドしたコレクションのプロパティを表示したいだけなら`DisplayMemberBinding`にプロパティをバインドする。
(サンプルプログラムの`Header="色"`の列を参照)

列のセルをいろいろ変えたいなら、`<GridViewColumn >`で`DisplayMemberBinding`に値をセット**「せずに」、**`<GridViewColumn.CellTemplate>`に`<DataTemplate>`をセットする。
(サンプルプログラムの`Header="コード"`の列を参照)

`DisplayMemberBinding`になにかバインドしてると、`<DataTemplate>`にセットした内容が反映されてくれないらしい。

追記
下記のページに、その辺の優先順位が書いていた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/e463e9b7-5bff-9a5f-49e1-61e24b8baaa3.png)

https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.gridviewcolumn?view=net-5.0#remarks

### styleがない

GridView や GridViewColumn はFrameworkElement を継承していないので、styleをもっておらず、同じ見た目の列を作りたいと思ってもリソースでstyleを作ってそれを使いまわすということができない様子。

# 参考

公式 GridView(ListViewのモードの一種)のカスタムの仕方

https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/controls/gridview-overview?view=netframeworkdesktop-4.8

http://var.blog.jp/archives/67281536.html