[WPF] Binding復習② リストで今選択している項目を`{Binding Path=/}`でバインドする

# もくじ

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

# やりたいこと

職場で、画面のxamlを見ていたら

```a.xaml
    <TextBlock Text="{Binding Path=/}"/>
```

みたいな感じで、`{Binding Path=/}`というのが出てきてなにこれ？となった。
調べたい。

# しらべたこと その1

`Path=/`は、コレクションの選択項目を参照しろ、ということになる。

**参考：**
++C++; // 未確認飛行 C ブログ

https://ufcpp.wordpress.com/2011/01/28/wpf-%E3%81%AE-binding-path/

確かめてみる。

## 試したコード その1

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

namespace WpfApp4
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion

        public ObservableCollection<SolidColorBrush> ColorList
        {
            get { return colorList; }
            set { colorList = value; OnPropertyChanged(nameof(ColorList)); }
        }
        public ObservableCollection<SolidColorBrush> colorList = new ObservableCollection<SolidColorBrush>();

        public MainWindow()
        {
            InitializeComponent();

            // 色のリストを作成(ListBoxのItemsSourceにバインドする)
            ColorList.Add(new SolidColorBrush(Colors.Blue) { Opacity = 0.5 });
            ColorList.Add(new SolidColorBrush(Colors.Red) { Opacity = 0.7 });
            ColorList.Add(new SolidColorBrush(Colors.Green) { Opacity = 0.9 });
            ColorList.Add(new SolidColorBrush(Colors.Yellow) { Opacity = 1.0 });
            ColorList.Add(new SolidColorBrush(Colors.Purple) { Opacity = 0.2 });

            this.DataContext = ColorList;
        }
    }
}
```

```MainWindow.xaml
<Window x:Class="WpfApp4.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:WpfApp4"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="400">
    <!-- コードビハインドで「this.DataContext = ColorList;」で色のListをDataContextにしてる -->
    <StackPanel>
        <TextBlock Text="{Binding Path=.}"/>
        <ListBox ItemsSource="{Binding Path=.}" IsSynchronizedWithCurrentItem="True" Margin="10"/>
        <ListBox ItemsSource="{Binding Path=.}" IsSynchronizedWithCurrentItem="True" Margin="10"/>
        <TextBlock Text="{Binding Path=/}" Background="{Binding Path=/}"/>
    </StackPanel>
</Window>
```

## 結果画面
一番上(最後にListにAddしたパープル)を選んだ時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/c03f44af-d46f-32cb-b3c0-edc8945f7f9b.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/241caebf-8dc4-1093-36b2-87ae76af67e5.png)
テキストブロックには、プロパティ`ColorList`のうち、ListBoxで選択された項目がBindingされてる。
TextにBindingした方には、カラーコードが出て、BackgroundにBindingした方にはその色が表示されている。

## ポイント

画面にはListBoxを2つ出していて、両方とも同じListにBindingしていて、かつ`IsSynchronizedWithCurrentItem`をTrueにしている。

こうすると、両方のListBoxの選択項目がシンクロする。

また、その下のTextBlockで`{Binding Path=/}`と書くことにより、ListBoxがItemsSourceにBindingしてるリストの中の、選択してる項目がBindingされることになる。

ListBoxの片方だけ`IsSynchronizedWithCurrentItem`をFalseにすると、2つのListBoxの選択項目がシンクロしなくなる。
またFalseにしたほうで項目を選んでも、TextBlockに反映されなくなる。

# しらべたこと その2

個人的にというか、自分のまわりでは、DataContextにListを直接入れたりすることはほぼやったことがなく、大体の場合、DataContextにはViewModelのクラスが入ってたり、Window(とかUserControl)のクラス自身が入ってたりする。

そういう場合にも、`/`が使えるのか確かめる。

## 試したコード その2

Bindingの部分を`{Binding Path=ColorList/}`という感じで、MainWindowクラスの中のColorListの**選択されてるやつ**ということにした。

```一部MainWindow.xaml.cs
this.DataContext = this;// Windowのクラス自身をDataContextにする
```

```一部MainWindow.xaml
        <TextBlock Text="{Binding ColorList}"/>
        <ListBox ItemsSource="{Binding ColorList}" IsSynchronizedWithCurrentItem="True" Margin="10"/>
        <ListBox ItemsSource="{Binding ColorList}" IsSynchronizedWithCurrentItem="True" Margin="10"/>
        <TextBlock Text="{Binding Path=ColorList/}" Background="{Binding Path=ColorList/}"/>
```

結果の画面は全く同じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/3a9d80cb-3284-30cd-eb23-e794cade883b.png)

ここからさらに、

```MainWindow.xaml
<TextBlock Text="{Binding Path=ColorList/Opacity}" Background="{Binding Path=ColorList/}" Opacity="{Binding Path=ColorList/Opacity}"/>
```

てな感じで「選択されてる項目のさらに中のプロパティ」みたいなこともできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/78694a18-82ca-5c3c-00a6-fe8ff4e66107.png)

# 参考

このMS
MS公式ドキュメントの、

https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/data/binding-declarations-overview?view=netdesktop-5.0#binding-path-syntax

下記にあたる部分。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/ebeef412-2501-7a6a-7320-4b0073f78b71.png)

この部分の説明がわかるようでよくわからなかったのだが、試してみるとなるほどという感じ。

この説明でいうところの「コレクション ビュー」というのは、ListをバインディングしているListBoxなどのことを言ってるのだと思う。(たぶん)