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


ComboBoxとModelの連携

概要

WPF in C# with MVVM using Caliburn Microの40分50秒目あたりからを参考に、前回までのテキストボックスとViewModelの連携を踏襲し、ComboBoxとのバインディングを試す。

完成形

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

Modelを追加する

今回も動画内容に沿って実装を行う。40分50秒めあたりからだけど、前回記事からの流れのまま開始するので、必要であれば参照のこと。

ModelsにPersonModelクラスを追加

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

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を使う模様。

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人ぶんつっこんでみる。

        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をバインドする。

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

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

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

ComboBoxにPeopleの内容が反映されるようになった。

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

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

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

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

まとめ

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

次の記事:Buttonを使う