今回は、以前にご紹介したMVVM(Model-View-ViewModel)フレームワークのPrism上で「SPREAD for WPF(スプレッド)」を使用する例をさらにパワーアップして、Prismの主要機能である「DI コンテナ」と「Region / Navigation」そして「Module」を利用するサンプルをご紹介します。
Prismの概要やPrismを使ったプロジェクトを作成するために必要なPrism Template Packのインストール方法については、前回の記事でご紹介しているので、ご参考にしていただければと思います。
1. 今回使用するPrismの機能
MVVMパターンのアプリケーション開発を支援するPrismには多くの便利な機能が用意されていますが、今回は、次の4つの機能を使って簡単なサンプルを作成します。
- ViewModel の実装を補佐してくれる機能
- アプリケーション全体で使用できるDIコンテナ機能
- 名前付き表示領域を管理するRegion / Navigation機能
- DLLによるプラグイン実装をサポートするModule機能
この中の「DIコンテナ」機能は、「Region / Navigation」と「Module」の機能を利用する際に欠かせないものです。
ここで簡単に用語について説明しておきます。
- Shell:Moduleを読み込むWindow(またはWindowが含まれているプロジェクト)
- Module:Shell内のWindowに配置するViewを含んだDLL(またはプロジェクト)
- Region:Viewの配置先となるWindow内のContentControl
- Navigation:Region にViewを追加・削除する操作
- View:WindowまたはUserControl
Prismの詳細については、下記をご参照ください。
ホームページ:http://prismlibrary.github.io/
サンプル:https://github.com/PrismLibrary/Prism-Samples-Wpf
【メモ】
今回使っている「Region / Navigation」の機能がPrismサンプルの
17-BasicRegionNavigation
に実装されているので、一度ご確認いただければと思います。
2. 作成するサンプルの概要
サンプルの機能
サンプルに配置している各ボタンの機能は、次のとおりです。
- Viewの表示:SPREADが配置されているViewを表示します
- Viewの非表示:SPREADが配置されているViewを非表示にします
- データの保存:データをXMLファイルに保存します
- 行の追加:新しい行を末尾に追加します
- 行の削除:カレント行を削除します
- 変更の確定:データソースに加えられた変更内容を確定します
- 変更の破棄:データソースに加えられた変更内容を破棄して元に戻します
最初の3つのボタンはShellのWindow
に配置されており、残りの4つのボタンはModuleのUserControl
にSPREADと一緒に配置されています。
サンプルの構造
モデルに含まれるデータソースは、前回と同じでコード(Code)、製品名(Name)、価格(Price)の3つのフィールドからなる製品データ一覧です。
SPREADは、前回はShellのMainWindow(Window
)上に配置しましたが、今回は別のModuleに含まれているViewA(UserControl
)上に配置します。そして、ShellのプロジェクトからModuleのプロジェクトを参照(Module機能)し、Module内のViewAをShell内のMainWindow内に表示(Region / Navigation機能)します。
つまり、親であるMainWindow内に子となるViewAを配置して、さらにその中に孫のSPREADを配置する形になります。
また、Shell内にあるデータソースをModule内のSPREADに連結するために、PrismのDIコンテナ機能を使ってデータソースのインスタンスをコンテナに登録し、それをModule内のViewModelのコンストラクタで取得しています。
MVVMの構成は次のようになっています。
- モデル:ProductModel.cs(Shell)
- ビュー:MainWindow.xaml(Shell)とViewA.xaml(Module)
- ビューモデル:MainWindowViewModel.cs(Shell)とViewAViewModel.cs(Module)
なお、今回のサンプルでも次の点を考慮して、できるだけ「イベントハンドラとコードビハインドよりもXAMLに記述する」ようにしています。
- テスト容易性
- 再利用性
- 可読性
3. メインプロジェクト(Shell)の作成
プロジェクトの生成
Prismのテンプレートを使ってShellとなるメインプロジェクトを作成します。
- Visual Studioを起動する
- [スタートページ]-[新しいプロジェクト]の検索欄に「prism」と入力する
- 表示されたリストから「Prism Blank App (WPF) C#」を選択する
- プロジェクトの保存先とプロジェクト名(SpreadWPF_Prism2)を指定する
- 表示された[PRISM PROJECT WIZARD]で「Unity」を選択して[CREATE PROJECT]ボタンをクリックする
- メニューの[ビルド]-[ソリューションのリビルド]を選択する
以上の操作でPrismのShellプロジェクトが自動的に生成されます。
Prismのテンプレートを利用するには、あらかじめPrism Template Packをインストールしておく必要があります。
※インストールの手順については、前回の記事をご参照ください。
モデル(ProductModel)の作成
先ほど作成したプロジェクトに「ProductModel」という名前のモデル用のクラスを追加し、下記のコードを記述します。
ここでは、データソースとしてDataSet
を使うことで、データを保持するXMLファイルへの保存と読込を簡素化しています。また、GetProducts
メソッドは、外部からDataTable
を取得するために用意しています。
ビュー(MainWindow)の作成
次の手順でViews
フォルダ内のMainWindow
ビューを変更します。各プロパティの設定内容については、下のXAMLを参照してください。
- Windowの各プロパティを設定します
- デフォルトで追加されているGridを削除します
- DockPanelを貼り付けます
- DockPanelのプロパティを設定します
- DockPanel内にStackPanelを貼り付けます
- StackPanelのプロパティを設定します
- StackPanel内に3つのButtonを貼り付けます
- 各Buttonのプロパティを設定します
- StackPanelの下にContentControlを貼り付けます
- ContentControlのプロパティを設定します
以上の操作を行ってMainWindow
のXAMLを次のようにします。
左端のButton:
CommandParameter
に設定した”ViewA”を引数にしてMainWindowViewModel
のNavigateCommand
メソッドを呼び出します。その結果、この後で作成するModuleのViewA
がContentControl
に読み込まれ、MainWindow
上に表示されます。
中央のButton:
空文字を引数にしてMainWindowViewModel
のNavigateCommand
メソッドを呼び出すことで、表示したViewA
を削除します。
右端のButton:
MainWindowViewModel
のSaveCommand
メソッドを呼び出して、ProductModel
内のDataSet
の内容をXMLファイルに保存するためのものです。
SPREADのライセンス作成とプロジェクトへ参照を追加するため、GcSpreadGridコントロールをContentControlの下に貼り付け、すぐに削除しておきます。
ビューモデル(MainWindowViewModel)の作成
ビューモデルは、Prismのテンプレートが自動で生成するViewModels
フォルダにあるMainWindowViewModel.cs
に次のように記述します。
ビューモデルに実装する機能は、次のとおりです。
- Navigationを実現するために必要なIRegionManagerの取得
- Region / Navigation機能を実行するNavigateCommandとNavigateメソッド
- データをXMLファイルに保存するSaveCommandとSaveDataメソッド
なお、MainWindowViewModel
のコンストラクタで取得しているIRegionManager
は、Prismが自動的に設定します。
Shell機能の実装
Shellの基本機能を実装するために、Shell側で行う重要なステップがもう1つあります。
ここに追加するコードは、SpreadWPF_Prism2プロジェクト(Shell)にNavigationプロジェクト(Module)を参照設定している必要があります。
そのため、ここに記載している内容は、次の「4. モジュールプロジェクト(Module)の作成」を行った後で実装してください。
ここでは、次の3つのメソッドを追加することで、Shellの重要な機能を実装します。
- OnStartupメソッド:データを保持しているXMLファイルの読み込み
- RegisterTypesメソッド:モデル(ProductModel)で取得したデータのインスタンスのコンテナへの登録
- ConfigureModuleCatalogメソッド:Module(NavigationModule)の読み込み
具体的には、プロジェクトに自動生成されるApp.xaml.cs
に次のように記述します。
4. モジュールプロジェクト(Module)の作成
プロジェクトの追加
次の手順で、PrismテンプレートのModuleプロジェクトをソリューションに追加します。
- Visual Studioのメニューで[ファイル]-[追加]-[新しいプロジェクト]を選択する
- 表示されたリストから「Prism Module (WPF) 」を選択する
- プロジェクト名(Navigation)を指定する
- [OK]ボタンをクリックする
- メニューの[ビルド]-[ソリューションのリビルド]を選択する
ビュー(ViewA)の作成
次の手順でViews
フォルダ内のViewA
ビューを変更します。各プロパティの設定内容については、下のXAMLを参照してください。
- UserControlの各プロパティを設定します
- デフォルトで追加されているGrid内のTextBlockを削除します
- GridのRowDefinitionsとColumnDefinitionsを設定します
- GcSpreadGridを貼り付けます
- GcSpreadGridのプロパティを設定します
- GcSpreadGridの下にButtonを4つ貼り付けます
- 各Buttonのプロパティを設定します
以上の操作を行ってViewA
のXAMLを次のようにします。
SPREAD本体:
SPREADのItemsSource
プロパティにビューモデルのProducts
プロパティを連結し、SelectedItem
プロパティにはSelectedProduct
プロパティを連結しています。これにより、モデルのデータがSPREADにデータ連結され、SPREAD上のカレント行が移動するたびにその行の情報がビューモデルに伝えられます。
SPREADの列:
SPREADの第1列から第3列に対応するデータのフィールド名を設定してデータ連結を可能にします。また、第1列はTextCellTypeに、第3列はNumberCellTypeに設定します。
Button:
4つのButton
のCommand
には、それぞれ該当するコマンド名をバインドします。これによって、ボタンをクリックしたときに目的の動作が実行されます。
ビューモデル(ViewAViewModel)の作成
ViewModels
フォルダ内のViewAViewModel.cs
に次のように記述します。
Prismでは、ModelViewのクラスでINotifyPropertyChangedインタフェースの機能を拡張したBindableBaseクラスを継承します。
これにより、PropertyChangedEventHandlerとOnPropertyChangedを実装する必要がなくなるので、プロパティの記述がとてもシンプルになります
Moduleのビューモデルに実装する機能は、次のとおりです。
- コンテナを経由したデータ(DataTable)の取得
- データを保持するDataTable型のProductsプロパティ
- SPREADのカレント行をビューと共有するSelectedProductプロパティ
- 行追加の処理を行うAddCommandとAddメソッド
- 行削除の処理を行うDeleteCommandとDeleteメソッド
- DataTable(DataSet)への変更を確定するAcceptCommandとAcceptメソッド
- DataTable(DataSet)への変更を破棄するRejectCommandとRejectメソッド
Module機能の実装
Prismが自動生成するNavigationModule.cs
ファイルを下のように変更します。
RegisterTypesメソッドに追加したコードによって、このModuleがコンテナに登録されてNavigation操作が可能になります。
以上でサンプルアプリケーションの完成です。
作成したサンプルは以下で公開しています。SPREAD for WPF 2.0J SP3で作成されています。
5. おわりに
次回は、PrismのInteractionRequest機能を使ってViewから別のダイアログをポップアップするサンプルをご紹介する予定です。
製品Webサイトでは、SPREAD for WPF 2.0Jのデモアプリケーションを公開しています。グリッド系コントロールの基本機能はもちろん、Excelライクな操作性や自由度の高い表レイアウトなど、数多くの機能が用意されていますので、以下より是非お試しください。