本文へスキップ
BecomeCoder

C# MVVMコース · 第7章 View ― WPFへ接続する · レッスン26

一覧表示 ― ItemsSourceとObservableCollection

ブラウザで完結

導入

WPFで一覧を表示する定番の組み合わせが、ListBox(やComboBox/DataGrid)の**ItemsSourceと、ViewModelが持つObservableCollection<T>**です。ItemsSourceにコレクションをバインドすると、コレクションの中身がそのまま一覧として描画されます。まずはこの土台だけを、実際に手を動かして確認しましょう。

説明

flowchart LR
    LB["ListBox(View)<br/>ItemsSource={Binding Tasks}<br/>DisplayMemberPath=Title"] --> OC["ObservableCollection&lt;TaskDto&gt;<br/>Tasks(ViewModel)"]
    OC -.CollectionChanged.-> LB
  • ItemsSource="{Binding Tasks}"で、ViewModelのTasksObservableCollection<TaskDto>)を一覧の元データにする
  • DisplayMemberPath="Title"で、各要素のどのプロパティを表示するかを指定する(第6章recordの位置引数がそのままプロパティ名になる)
  • List<T>ではなくObservableCollection<T>を使う理由は、要素が増減したときに自動で画面へ通知が飛び、一覧の再描画が自動で起きるから(レッスン21の復習)

やってみよう

下の実行ウィジェットには、まだTasksへ要素を追加する手段(ボタン)がありません。次のレッスンで追加機能をつなぐ前に、まずは「空のコレクションが正しくListBoxに接続されている」ことと、XAMLの各属性の役割を確認しましょう。

  1. 右のプレビューでListBoxが(空のまま)表示されていることを確認する
  2. DisplayMemberPath="Title"DisplayMemberPath="IsCompleted"に書き換えて保存し、プレビューが再描画されることを確認する(一覧は空なので見た目の差は出ないが、エラーにならないことがわかる)
  3. HeightMarginの数値を変えて、レイアウトが変わることを確認する

確認ポイント

  • ItemsSourceTasksObservableCollection<TaskDto>)を指していること
  • DisplayMemberPathで表示するプロパティ名を指定できること
  • XAMLを書き換えるとプレビューが再描画されること

まとめ

  • ListBoxItemsSourceにコレクションをバインドすると一覧表示になる
  • DisplayMemberPathで「どのプロパティを表示するか」を指定する
  • ObservableCollection<T>は増減のたびに画面へ自動通知する(List<T>にはできない)

次回: TextBoxCommandをつないで、実際にタスクを追加できるようにします。

実際に動かしてみよう

上がXAML(View)、真ん中がViewModelのC#風コード、右がプレビューです。ViewModelのプロパティやRelayCommandを書き換えると、プレビュー側の一覧・入力・ボタンの有効/無効にその場で反映されます(本物のC#コンパイルではなく、単純なプロパティ・計算プロパティ・コマンドの実行/CanExecuteを再現した学習用エンジンです。複雑なLINQや独自クラスのメソッド呼び出しなどは対象外です)。本文のコードを書き換えて、Viewとの連動を確かめながら進めましょう。

MVVM (XAML + ViewModel) プレビュー

書いた XAML(View) と ViewModel(C#風) をその場で連携させて動かす学習用プレビューを読み込みます(本物のWPF/MVVMではなく、単純な自動プロパティ・計算プロパティ(=>)・ICommand(RelayCommandのexecute/CanExecute)・{Binding}の双方向バインディングを再現したものです。独自クラスのメソッド呼び出し・複雑なLINQ・非同期処理・DI・CommandParameterは実行されません)。
スクロールして表示された時点でも自動で読み込まれます。