Caliburn.Microを用いてWPFアプリケーションを作成する(3)

# ComboBoxとModelの連携

## 概要

[WPF in C# with MVVM using Caliburn Micro](https://www.youtube.com/watch?v=laPFq3Fhs8k)の40分50秒目あたりからを参考に、[前回までのテキストボックスとViewModelの連携](https://qiita.com/paichi81@github/items/32bc798536ac8c1b35a5)を踏襲し、ComboBoxとのバインディングを試す。

### 完成形

* 表示の値Keyと選択値Valueをもつコンボボックスをもつ単一ウィンドウアプリを作る。
* データ用のModelクラスを扱う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/db95088f-b26c-da20-e617-1261a8faee0a.png)


## Modelを追加する

今回も動画内容に沿って実装を行う。40分50秒めあたりからだけど、[前回記事](https://qiita.com/paichi81@github/items/32bc798536ac8c1b35a5)からの流れのまま開始するので、必要であれば参照のこと。


### ModelsにPersonModelクラスを追加

ソリューションエクスプローラでModelsフォルダ下にクラスを追加。
中身は単に FirstNameとLastNameを保持するstringだけとする。

```cs:PersonModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WPFtut01.Models
{
    public class PersonModel
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}
```

### ViewModelを編集

選んだ際のComboBoxとデータをやりとりするBindableCollectionと。中身のPersonModelを追加する。
MVVMで紐づけられるように、単純なCollectionやDictionaryでなくBindableCollectionを使う模様。

```cs:ShellViewModel.cs(抜粋)
		private BindableCollection<PersonModel> _people = new BindableCollection<PersonModel>();

		public BindableCollection<PersonModel> People
		{
			get { return _people; }
			set { _people = value; }
		}

		private PersonModel _selectedPerson;

		public PersonModel SelectedPerson
		{
			get { return _selectedPerson; }
			set {
				_selectedPerson = value;
				NotifyOfPropertyChange(()=>SelectedPerson);
			}
		}
```

ComboBoxに入るグループは People とし、選択される個人名は SelectedPerson としている。

### Modelのコンストラクタを作成

前回同様、VS2019上で 'ctor'とタイプし、タブキーを2回押すとsnippet展開される。
今回はPeopleにPersonを4人ぶんつっこんでみる。

```cs
		public ShellViewModel()
		{
			People.Add(new PersonModel { FirstName = "カタリナ", LastName = "クラエス" });
			People.Add(new PersonModel { FirstName = "マリア", LastName = "キャンベル" });
			People.Add(new PersonModel { FirstName = "メアリ", LastName = "ハント" });
			People.Add(new PersonModel { FirstName = "ソフィア", LastName = "アスカルト" });
		}
```

### ViewにComboBoxを追加する

ShellView.xamlにコメントを入れ、ここまで編集してきた内容を整理。
ComboBoxを追加し、x:NameにPeopleを指定し、次のようにSelectedItemをSelectedPersonをバインドする。

```xml:ShellView.xaml(抜粋)
        <ComboBox Grid.Row="3" Grid.Column="1" x:Name="People"
                  SelectedItem="{Binding Path=SelectedPerson, Mode=OneWayToSource}"
                  DisplayMemberPath="FirstName"></ComboBox>
```

追加内容としては、選択だけなのでOneWayToSource。


### ここまでの内容でテスト実行

ComboBoxにPeopleの内容が反映されるようになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/c4fb9d58-e15c-7483-052d-eca721ceac86.png)

### 選択Valueが表示されるようTextBlockを追加

```xml
   <TextBlock Grid.Row="3" Grid.Column="2" x:Name="SelectedPerson_LastName" />
```

x:Nameの値は、アンダースコア付きでプロパティ呼び出しになる（らしい）
ここまでの内容を実行すると完成形のとおりになる。

コンボボックスを変更すると、TextBlockが連動して変更されるようになる。


## まとめ

* WinFormsなどのようにComboBoxの変更イベントを関数で作成するわけではない
* ComboBoxへ紐づけるオブジェクトはCaliburn.Microが用意しているBindableCollectionを使う
* 選択値の取得の アンダースコア付きプロパティとかは、ちゃんと公式ドキュメント等参照したい

次の記事：[Buttonを使う](https://qiita.com/paichi81@github/items/f9720b8a46b5948254a9)