今回は、WPFと密接な関係にあるMVVM(Model-View-ViewModel)パターンのアプリケーション開発を強力にサポートしてくれるPrismフレームワーク上で「SPREAD for WPF(スプレッド)」を使用する例をご紹介します。
1. MVVMとPrism
MVVMは、マイクロソフトのWPFとSilverlightを対象として考えられたアーキテクチャパターンで、モデル(Model)とビュー(View)そしてビューモデル(ViewModel)の3層構造になっています。
一方、Prismは、Prism Libraryの冒頭で述べられているように「疎結合で保守とテストを容易にするXAMLアプリケーションをWPF、Windows 10 UWP、そしてXamarin Formsで構築するためのフレームワーク」です。このように、WPFとMVVMそしてPrismは互いに密接な関係にあります。
MVVMパターンのアプリケーション開発を支援するPrismには多くの便利な機能が用意されていますが、ここでは、次の2つの機能を使って簡単なサンプルを作成します。
- ViewModel の実装を補佐してくれる機能
- コントロールのイベントにコマンドをバインドする機能
なお、Prismの詳細については、下記をご参照ください。
ホームページ:http://prismlibrary.github.io/
サンプル:https://github.com/PrismLibrary/Prism-Samples-Wpf
2. Prism Template Packのインストール
Visual StudioのWPFプロジェクトでPrismを利用するには、まず「Prism Template Pack」をインストールしておく必要があります。
その手順が、Prism LivraryのDocumentationページ(英文)に記載されていますので、ご参考にしてください。
[Documentation / Getting Started / Download and Setup Prism]
実際の操作は次のようになります。
- Visual Studioを起動する
- Visual Studioのメニューから [ツール]-[拡張機能と更新プログラム] を選択する
- 検索欄に「prism」と入力し、表示されたリストから「Prism Template Pack」の[ダウンロード]ボタンをクリックする
- 指示に従って操作した後、Visual Studioを閉じる
- 「Prism Template Pack」のインストールが行われる
3. SPREADとPrismを使ったサンプルの作成
今回作成するのは、コード(Code)、製品名(Name)、価格(Price)の3つのフィールドからなる製品データ一覧をSPREADに表示し、選択された行の製品名と価格をテキストブロックに表示するという簡単なWPFアプリケーションです。
MVVMの構成は次のようになっています。
- モデル:ProductModel.cs
- ビュー:MainWindow.xaml
- ビューモデル:MainWindowViewModel.cs
モデルのProductModel.cs
は設計した構造に従ってデータを生成するクラスなので独自に作成しますが、ビューのMainWindow.xaml
とビューモデルのMainWindowViewModel.cs
は、Prismのテンプレートが自動で生成してくれます。そして、SPREADはビューに設定することになります。
なお、今回のサンプルでは次の点を考慮して、できるだけ「イベントハンドラとコードビハインドよりもXAMLに記述する」ようにしました。
- テスト容易性
- 再利用性
- 可読性
Prismを利用するプロジェクトの作成
まずはじめに、Prismのテンプレートを使ったプロジェクトを作成します。
- Visual Studioを起動する
- [スタートページ]-[新しいプロジェクト]の検索欄に「prism」と入力する
- 表示されたリストから「Prism Blank App (WPF) C#」を選択する
- プロジェクトの保存先とプロジェクト名(SpreadWPF_Prism)を指定する
- 表示された[PRISM PROJECT WIZARD]で「Unity」を選択して[CREATE PROJECT]ボタンをクリックする
- メニューの[ビルド]-[ソリューションのリビルド]を選択する
以上で準備が整いました。
モデル(Model)の作成
先ほど作成したプロジェクトに「ProductModel」という名前の新規クラスを追加して、次のコードを記述します。
SPREADのヘルプなどでは、データのクラスにObservableCollection<>
の派生クラスが使われることがありますが、ここではDataSet
とDataTable
を使います。
ビューモデルでGetProducts
メソッドが呼び出されたときに、データを格納したDataTable
がビューモデルに渡されます。
ビュー(View)の作成
ビューのMainWindow
には、SPREADと4つのTextBlock
を貼り付けます。なお、SPREADを貼り付ける前に、デフォルトで追加されているContentControl
を削除しておきます。
あとは、下のXAMLをコピーするだけです。
上記のXAMLにあるWindow
タグのxmlns:i
は、SPREADのSelectionChanged
イベントをビューモデルのSelectedCommand
に関連付けるために使う<i:Interaction.Triggers>
に必要なものです。
ここで使っているイベントとコマンドを関連付ける手法は、Prismサンプルの
29. Interactivity – InvokeCommandAction
にありますので、一度ご確認いただければと思います。
Prismに関連する次の2つは、プロジェクトが作成されるときにPrismのテンプレートが自動的に設定します。
<Window.DataContext>
でモデルのデータをSPREADに連結する準備をしておきます。
SPREADのItemsSource
プロパティにビューモデルのProducts
プロパティを連結し、SelectedItem
プロパティにはSelectedProduct
プロパティを連結します。これにより、モデルのデータがSPREADにデータ連結され、SPREAD上のカレント行が移動するたびにその行の情報がビューモデルに伝えられます。
SPREADの第1列から第3列までは、Focusable="False"
およびLocked="True"
を設定してフォーカスの移動と編集を禁止します。また、対応するデータのフィールド名を設定してデータ連結されるようにしておきます。
TextBlock
のText
には、ビューモデルのProductName
プロパティとProductPrice
プロパティを連結します。これによって、SPREAD上でカレント行が移動するたびに、該当する製品名と価格がTextBlock
に表示されます。
ビューモデル(ViewModel)の作成
ビューモデルは、Prismのテンプレートが自動で生成するViewModels
フォルダにあるMainWindowViewModel.cs
に次のように記述します。
ここで気になるのが、MainWindowViewModel : BindableBase
の部分です。ビューモデルのクラスはINotifyPropertyChanged
インタフェースを実装することが多いと思いますが、Prismではその機能を拡張したBindableBaseクラスを継承します。これにより、PropertyChangedEventHandlerとOnPropertyChangedを実装する必要がなくなるので、プロパティの記述がとてもシンプルになります
今回のビューモデルに実装する機能は、次のとおりです。
- モデルからのデータ取得
- データを保持するDataTable型のProductsプロパティ
- SPREADのSelectionChangedイベントに対応したSelectedCommand
- SelectedCommandの処理を行うOnPropertyChangedメソッド
- TextBlockに製品名を渡すString型のProductNameプロパティ
- TextBlockに価格を渡すInt32型のProductPriceプロパティ
- SPREADのカレント行をビューと共有するSelectedProductプロパティ
以上でサンプルアプリケーションの完成です。
補足
今回はPrismの機能を使うことに焦点をおいたので「コントロールのイベントにコマンドをバインドする」Prismの機能を使いましたが、SelectedProduct
プロパティの実装を次のようにする方が一般的かもしれません。
作成したサンプルは以下で公開しています。SPREAD for WPF 2.0J SP3で作成されています。
4. おわりに
PrismにはMVVMを実現するための機能が多数用意されていますが、今回はそのうちDIやRegionなどの主要機能の説明が出来なかったので、次回以降その辺もやっていきたいと思います。
また、以下の当ブログやCodeZineの記事では、MVVMパターンでSPREAD for WPFの機能を活用する方法や、業務アプリケーションの実践的なアーキテクチャ設計について解説していますので、これらもご参考にしていただければと思います。
※旧バージョンの1.0Jをもとに書かれた記事が一部含まれていますが、最新の2.0Jでも有効な内容です。
製品Webサイトでは、SPREAD for WPF 2.0Jのデモアプリケーションを公開しています。グリッド系コントロールの基本機能はもちろん、Excelライクな操作性や自由度の高い表レイアウトなど、数多くの機能が用意されていますので、以下より是非お試しください。