Prism + FlexGrid for WPFで明細表のViewをポップアップする

以前にMVVM(Model-View-ViewModel)フレームワークのPrismとSPREAD for WPFを題材にして3つの記事を公開しましたが、今回は、その記事の中で3番目にご紹介した別のViewをポップアップする方法を、「ComponentOne(コンポーネントワン)」の「FlexGrid for WPF(フレックスグリッド)」でも試してみたいと思います。



  1. 使用するPrismの機能
  2. 作成するサンプルの概要
  3. メインプロジェクト(Shell)の作成
  4. モジュールプロジェクト(Module)の作成
  5. おわりに


1. 使用するPrismの機能

MVVMパターンのアプリケーション開発を支援するPrismの機能のうち、今回は次の5つを使って簡単なサンプルを作成します。

  • ViewModel の実装を補佐してくれる機能
  • アプリケーション全体で使用できるDIコンテナ機能
  • 名前付き表示領域を管理するRegion / Navigation機能
  • DLLによるプラグイン実装をサポートするModule機能
  • ViewModelとViewの間で通信を行うInteractionRequest機能

この記事のサンプルで子画面をポップアップするときに利用しているのが、5番目の「InteractionRequest」の機能です。親画面のFlexGridのアクティブ行を特定する情報を子画面に渡すためにこの機能を使っています。

ここで簡単に用語について説明しておきます。

  • Shell:Moduleを読み込むWindow(またはWindowが含まれているプロジェクト)
  • Module:Shell内のWindowに配置するViewを含んだDLL(またはプロジェクト)
  • Region:Viewの配置先となるWindow内のContentControl
  • Navigation:Region にViewを追加・削除する操作
  • View:WindowまたはUserControl

Prismの詳細については、下記をご参照ください。

Prismのホームページとサンプル

ホームページ:http://prismlibrary.github.io/
サンプル:https://github.com/PrismLibrary/Prism-Samples-Wpf

【メモ】

今回使っている「InteractionRequest」の機能がPrismサンプル
 28-CustomRequest

に実装されているので、ご確認いただければと思います。

2. 作成するサンプルの概要

サンプル

サンプルの機能

サンプルに配置している各ボタンの機能は、次のとおりです。

  • Viewの表示:FlexGridが配置されているViewを表示します
  • Viewの非表示:FlexGridが配置されているViewを非表示にします
  • 明細の表示:明細画面をポップアップします
  • 戻る:子画面を閉じて親画面に戻ります

最初の2つのボタンはShellのWindowに配置されており、3つ目のボタンはModule内の親画面用のUserControlにFlexGridと一緒に配置されています。最後のボタンは、Module内の明細画面用のUserControlにFlexGridと一緒に配置されています。

データの構成

モデルに含まれるデータソースは、親画面のFlexGridに表示されるOutlineテーブルと、明細画面のFlexGridに表示されるDetailテーブルから構成されています。本来、これらのテーブルは、データベース内の正規化された複数のテーブルから作成されますが、ここでは直接これらのテーブルを作成しています。

各テーブルのフィールドは、次のとおりです。

  • Outline:Class(分類)+Quantity(数量)+Amount(金額)
  • Detail:Code(コード)+Name(品名)+Price(単価)+Class(分類)+Quantity(数量)+Amount(金額)

サンプルの構造

ShellのMainWindow(Window)には、別プロジェクトのModuleに含まれているViewA(UserControl)が配置され、そのViewA上にはOutlineテーブルを表示するFlexGridがあります。また、同じModule内にあるDetail(UserControl)にはDetailテーブルを表示するFlexGridが配置されており、ViewAからポップアップされます。

また、Shell内にあるデータソースをModule内の2つのFlexGridに連結するために、PrismのDIコンテナ機能を使ってデータソースのインスタンスをコンテナに登録し、それをModule内のViewAViewModelとDetailViewModelのコンストラクタで取得しています。

MVVMの構成は次のようになっています。

  • モデル:ProductModel.cs(Shell)
  • ビュー:MainWindow.xaml(Shell)とViewA.xaml(Module)およびDetail.xaml(Module)
  • ビューモデル:MainWindowViewModel.cs(Shell)とViewAViewModel.cs(Module)およびDetailViewModel.cs(Module)
【メモ】

このサンプルでは、次の点を考慮して、できるだけ「イベントハンドラとコードビハインドよりもXAMLに記述する」ようにしています。

  • テスト容易性
  • 再利用性
  • 可読性

3. メインプロジェクト(Shell)の作成

ShellとなるメインプロジェクトのFlexGridWPF_Prismは、次の手順で作成します。

これらの手順に先立ってPrismのテンプレートである「Prism Template Pack」を開発環境にインストールしておく必要があります。
「Prism Template Pack」のインストールについては、下記の記事で詳しく手順を解説しているので、そちらをご参照ください。

プロジェクトの生成

最初に、Prismのテンプレートを使ってShellとなるメインプロジェクトを作成します。

  1. Visual Studioを起動する
  2. [スタートページ]-[新しいプロジェクト]の検索欄に「prism」と入力する
  3. 表示されたリストから「Prism Blank App (WPF) C#」を選択する
  4. テンプレートの選択
  5. プロジェクトの保存先とプロジェクト名(FlexGridWPF_Prism)を指定する
  6. 表示された[PRISM PROJECT WIZARD]で「Unity」を選択して[CREATE PROJECT]ボタンをクリックする
  7. コンテナの選択
  8. メニューの[ビルド]-[ソリューションのリビルド]を選択する

以上の操作でPrismのShellプロジェクトが自動的に生成されます。

モデル(ProductModel)の作成

先ほど作成したプロジェクトに「ProductModel」という名前の新規クラスを追加して、次のコードを記述します。

データのクラスにObservableCollection<>の派生クラスが使われることがありますが、ここでは、データソースとして前述の2つのDataTableを含むDataSetを使っています。また、外部からこのDataSetを取得するためにGetSalesメソッドを用意しています。

ビュー(MainWindow)の作成

MainWindowビュー

次の手順でViewsフォルダ内のMainWindowビューを変更します。各プロパティの設定内容については、下のXAMLを参照してください。

  1. Windowの各プロパティを設定します
  2. デフォルトで追加されているGridを削除します
  3. DockPanelを貼り付けます
  4. DockPanelのプロパティを設定します
  5. DockPanel内にStackPanelを貼り付けます
  6. StackPanelのプロパティを設定します
  7. StackPanel内に2つのButtonを貼り付けます
  8. 各Buttonのプロパティを設定します
  9. StackPanelの下にContentControlを貼り付けます
  10. ContentControlのプロパティを設定します

以上の操作を行ってMainWindowのXAMLを次のようにします。

左のButton:
CommandParameterに設定した”ViewA”を引数にしてMainWindowViewModelNavigateCommandメソッドを呼び出します。その結果、この後で作成するModuleのViewAContentControlに読み込まれ、MainWindow上に表示されます。

右のButton:
空文字を引数にしてMainWindowViewModelNavigateCommandメソッドを呼び出すことで、表示したViewAを削除します。

【注記】

FlexGridのライセンスを生成し、プロジェクトへ参照を追加するため、C1FlexGridコントロールをContentControlの下に貼り付け、すぐに削除しておきます。

ビューモデル(MainWindowViewModel)の作成

ビューモデルは、Prismのテンプレートが自動で生成するViewModelsフォルダにあるMainWindowViewModel.csに次のように記述します。

ビューモデルに実装する機能は、次のとおりです。

  • Navigationを実現するために必要なIRegionManagerの取得
  • Region / Navigation機能を実行するNavigateCommandとNavigateメソッド

なお、MainWindowViewModelのコンストラクタで取得しているIRegionManagerは、Prismが自動的に設定します。

Shell機能の実装

Shellの基本機能を実装するために、Shell側で行う重要なステップがもう1つあります。

【メモ】

ここに追加するコードは、FlexGridWPF_Prismプロジェクト(Shell)にNavigationプロジェクト(Module)を参照設定している必要があります。
そのため、ここに記載している内容は、次の「4. モジュールプロジェクト(Module)の作成」を行った後で実装してください。

ここでは、次の2つのメソッドを追加することで、Shellの重要な機能を実装します。

  • RegisterTypesメソッド:モデル(ProductModel)で取得したデータのインスタンスのコンテナへの登録
  • ConfigureModuleCatalogメソッド:Module(NavigationModule)の読み込み

具体的には、プロジェクトに自動生成されるApp.xaml.csに次のように記述します。


4. モジュールプロジェクト(Module)の作成

プロジェクトの追加

次の手順で、PrismテンプレートのModuleプロジェクトをソリューションに追加します。

  1. Visual Studioのメニューで[ファイル]-[追加]-[新しいプロジェクト]を選択する
  2. 表示されたリストから「Prism Module (WPF) 」を選択する
  3. プロジェクト名(Navigation)を指定する
  4. Moduleプロジェクトの追加
  5. [OK]ボタンをクリックする
  6. メニューの[ビルド]-[ソリューションのリビルド]を選択する

ビュー(ViewA)の作成

ViewA

次の手順でViewsフォルダ内のViewAビューを変更します。各プロパティの設定内容については、下のXAMLを参照してください。

  1. UserControlの各プロパティを設定します
  2. デフォルトで追加されているGrid内のTextBlockを削除します
  3. GridのRowDefinitionsを設定します
  4. C1FlexGridを貼り付けます
  5. C1FlexGridのプロパティを設定します
  6. C1FlexGridの下にButtonを貼り付けます
  7. Buttonのプロパティを設定します

以上の操作を行ってViewAのXAMLを次のようにします。

FlexGrid本体:
FlexGridのItemsSourceプロパティにビューモデルのOutlineプロパティを連結し、SelectedItemプロパティにはSelectedProductプロパティを連結しています。この設定により、モデルのデータがFlexGridにデータ連結され、FlexGrid上のアクティブ行が移動するたびにその行の情報がビューモデルに伝えられます。

FlexGridの列:
FlexGridの第1列から第3列に対応するデータのフィールド名を設定してデータ連結を可能にします。

Button:
ButtonCommandにはShowDetailCommandをバインドします。これによって、ボタンをクリックしたときに明細画面がポップアップされます。

ビューモデル(ViewAViewModel)の作成

ViewModelsフォルダ内のViewAViewModel.csに次のように記述します。

ViewAのビューモデルに実装する機能は、次のとおりです。

  • コンテナを経由したデータ(DataSet)の取得
  • データを保持するDataTable型のOutlineプロパティ
  • FlexGridのアクティブ行をビューと共有するSelectedProductプロパティ
  • 明細画面をポップアップするShowDetailCommandとShowDetailメソッド
  • 明細画面との通信を行うShowDetailRequest(InteractionRequestクラス)

ユーザーコントロールの追加

次の手順で、PrismテンプレートのユーザーコントロールをNavigationプロジェクトに追加します。

  1. Visual Studioのソリューションエクスプローラーで[Navigation]プロジェクトを右クリックする
  2. コンテキストメニューから[追加]-[新しい項目]を選択する
  3. 表示されたリストから「Prism UserControl (WPF) 」を選択する
  4. View名(Detail.xaml)を指定する
  5. ユーザーコントロールの追加
  6. [追加]ボタンをクリックする

ビュー(Detail)の作成

Detail

次の手順でViewsフォルダ内のDetailビューを変更します。各プロパティの設定内容については、下のXAMLを参照してください。

  1. UserControlの各プロパティを設定します
  2. デフォルトで追加されているGrid内のTextBlockを削除します
  3. GridのRowDefinitionsを設定します
  4. C1FlexGridを貼り付けます
  5. C1FlexGridのプロパティを設定します
  6. C1FlexGridの下にButtonを貼り付けます
  7. Buttonのプロパティを設定します

以上の操作を行ってDetailのXAMLを次のようにします。

FlexGrid本体:
FlexGridのItemsSourceプロパティにビューモデルのSalesプロパティを連結しています。これにより、モデルのデータがFlexGridにデータ連結され、親画面のFlexGrid上のアクティブ行に対応した明細情報が表示されます。

FlexGridの列:
FlexGridの第1列から第4列に対応するデータのフィールド名を設定してデータ連結を可能にします。

Button:
ButtonCommandにはCloseCommandをバインドします。これによって、ボタンをクリックしたときに明細画面が閉じられます。

ビューモデル(DetailViewModel)の作成

ViewModelsフォルダ内のDetailViewModel.csに次のように記述します。

Detailのビューモデルに実装する機能は、次のとおりです。

  • コンテナを経由したデータ(DataSet)の取得
  • データを保持するDataView型のSalesプロパティ
  • 明細画面を閉じるCloseCommandとCloseInteractionメソッド
  • 親画面との通信に使う INotificationn型のNotificationプロパティ
  • インタラクションの終了処理に使用するAction型のFinishInteractionプロパティ

Module機能の実装

Prismが自動生成するNavigationModule.csファイルを下のように変更します。

RegisterTypesメソッドに追加したコードによって、このModuleがコンテナに登録されてNavigation操作が可能になります。

以上でサンプルアプリケーションの完成です。


作成したサンプルはこちらで公開しています。FlexGrid for WPF(ComponentOne 2019J v2)で作成されています。NuGetパッケージを復元して実行してください。


5. おわりに

製品Webサイトでは、ComponentOne for WPFのデモアプリケーションを公開しています。FlexGrid for WPFをはじめとする数多くのコントロールとライブラリが用意されていますので、以下より是非お試しください。

\  この記事をシェアする  /