Prism UI 合成 QuickStart

 

http://msdn.microsoft.com/en-us/library/ff921174(v=pandp.40)

ビジネスシナリオ

UI 合成 の サンプルは、架空のリソース管理システムに基づいています。メインウィンドウは、さらに大きなシステムのサブセットを表現しています。このウィンドウで、ユーザーは、従業員についての詳細な情報を確認することができ、連絡先を更新することができます。

prism_qs_ui01

ビルドと実行

  1. Silverlight only – Open QS – UI Composition QuickStart.bat を実行するとソリューションが起動する
  2. UIComposition.Web プロジェクトを右クリックし、スタートアッププロジェクトに設定を選択
  3. F5 で実行

ウォークスルー

1.メインウィンドウには、従業員のリストが表示されている

prism_qs_ui02

2.従業員の名前をクリックすると、動的に View がロードされ、詳細が表示される

prism_qs_ui03

3.他のタブを表示すると、追加の情報が表示される

prism_qs_ui04

実装について

このサンプルで重要なのは、Region の利用と、View を発見し、注入する方法

prism_qs_ui05

  • Shell Vew :  アプリケーションのメインウィンドウ。Left および Main Region を含んでいる
  • Left Region : このRegion は、View を見つけ出し、業員リストViewを含む
  • Employees List View : 従業員リスト
  • Main Region : 従業員サマリーView(Employees Summary View) を注入する
  • Employees Summary View : 従業員のタブ Region に従業員情報を View注入を行い、表示する
  • Tab Region : 従業員サマリーView(Employees Summary View) の中にあり、従業員詳細(Employee Details) および プロジェクト(Employee Project) View を持つ
  • Employee Detals View : 選択された従業員の詳細を表示
  • Employees Project View : 従業員が従事しているプロジェクトリストを表示

UI の組み立て

サンプルでは、View の発見とViewの注入を行っている

XAML で Region を設定する

  • Shell は ShellView.xaml にて、LeftRegionMainRegion の2つの Region を定義する
  • EmployeeSummaryView.xamlにて、EmployeeSummaryView  は、Tab コントロールを含み、TabRegion を 定義している
  • EmployeeSummaryView.xmalにて、TabRegion は、選択された従業員への参照を提供する、RegionContext を定義している

View の表示

  1. App.xaml.cs の Application_Startup メソッドは、Bootstrapper を生成し、起動する
  2. Bootstrapper の CreateModuleCatarog メソッドで、モジュールカタログが設定からロードされる。このモジュールカタログは、ModuleInit クラスに実装された EployeeModule のみを定義しており、起動後、直ちにPrismによりロードされる
  3. EmployeeModule で、ModuleInit クラスのInitialize メソッドがBootstrapper から呼び出される。このメソッドは、さまざまなことを行う。
    1. IEmployeeDataService の登録
    2. MainRegionController の生成
    3. ラムダ式を利用し、EmployeeListViewLeftRegion に登録
    4. EmployeeDetailView および EmployeeProjectsViewTabRegion に登録
  4. その後、Bootstrapper の CreateShell メソッドが呼び出され、LeftRegionおよびMainRegion を含む、ShellView のインスタンスが生成される
  5. LeftRegion の生成にて、Prism は、LeftRegion に登録されたラムダ式によりインスタンス化されたEmployeeListView をアクティブ化し表示する
  6. MainRegion には、View が登録されていないので、なにも表示されない

EmployeeListView で従業員が選択されると

  • MainRegionControllerEmployeeSelected メソッドが EmployeeSelectedEvent を購読していることにより、EventAggreagator を通して呼び出される。このイベントは、EmployeeListViewModel クラスのSelectedEmployeeChanged メソッドから発行される。

EmployeeSelected メソッドで実行されること

  1. 選択された従業員が、EmployeeDataService から参照される
  2. MainRegion RegionManager から参照され、メソッドは、EmployeeSummaryView という名前のViewを見つけようとする。というのは、このViewはまだ生成されておらず、コンテナからインスタンスが参照され、明示的にViewがMainRegion に注入される。
  3. EmployeeSummaryView が生成されるとき、TabRegion も生成される。TabRegion は、RegionContext を保持しており、CurrentEmployee に結びつけられる(EmployeeSummary.xaml) このとき、以下のことが起こる。
    1. Prism は、TabRegion が複数のViewを持っており、EmployeeDetailsView および EmployeeProjectsView のインスタンスを生成し、表示すべきであることを決定する。それぞれのView は、RegionContext の PropertyChange イベントを購読している
    2. RegionContext のバインドが更新されると、PropertyChanged イベントがトリガーされる
    3. EmployeeDetailsView および EmployeeProjectsView RegionContext プロパティが変更された通気を受け、結びつけられた View Model は更新されるため、選択された従業員が表示される

View の発見と注入の適用

View を発見する手法では、モジュールでコレクションに格納されたペア(View型とRegion名) にもとづいて登録された、 Regionの内側にViewを引き込む。この登録は、RegionViewRegistory という名前。Region が生成されるとき、RegionViewRegistory は、Region名に結びつけられたすべてのView型を探しだす。一致するViewが生成され、Regionに引き込む。この手法を利用するとき、Region インスタンスは、生成し注入するViewを探すための名前を明示的には保持しない。

一般的に、他のViewにホストされるViewは、子Viewで利用できるようにコンテキストを保持する。サンプルでは、動的に子Viewをロードしたときに、従業員の詳細を表示するために、どの従業員が現在選択されているかを知る必要がある。

Viewの注入手法は、View を すでに存在している Region の押し込むことを許可する。これは、Viewのインスタンスを生成することを要求し、Region への参照を取得し、それぞれを Region の Add メソッドを使ってRegionViewRegisory で結びつける。

View 発見手法とView注入手法

  • View 発見モデルには、タイミングの問題がない。例えば、あるモジュールがViewをRegionに追加することを試みる場合に、生成されていないということがない。
  • 同じRegionの複数のインスタンスを表示するのが簡単。なぜなら、特定Regionのインスタンスを見つけ、Viewに注入するための のスコープ管理について知る必要がないため。
  • RegionViewRegistory クラスに、GetContents メソッドを利用して、特定のRegionに結びつけられたすべてのViewを取得する問い合わせを投げることができる。例えば、このリストは、メニューに対応付けられる。
    • Viewの発見と合成において、Regionは、Visual Treeに追加されるとすぐに配置される。なので、ViewがRegion に追加されたら、制御しにくい。もし、View を狙った時にロードしたい場合、Viewの発見手法では困難。
    • サンプルでは、DetailRegion Regionは、EmployeeDetails View を取得し押し込む。View注入モデルは、ここでは、スコープ付きRegionの利用法を見せるために使われている。従業員を選択したとき、新しい EmployeeDetailsView が生成され、必要なら、EmployeeController により、DetailRegion Regionに押し込まれる。
  • View の発見と合成は、Regionが同時に同じViewの複数のインスタンスを持つ場合など、スコープ付きRegion Manager が必要な場合は使用すべきでない。なぜなら、Region は、Region Manager から、一意な名前で登録されているViewを取得するため。
    • サンプルでは、リストから従業員が選択された時に、いくつかのEmployeeDetailsView のインスタンスが生成され、メモリに保持される。それぞれのViewは、独自に TabRegion をもっているため、Viewhaそれぞれ独自の Region Manager を必要とする。
    • あたらしい TabRegion が生成されるとき、Project モジュールに登録された、ProjectsListView の新しいインスタンスも引き出され、表示される。

View の登録

Prism ライブラリのRegionViewRegisotry クラスは、Region名、View型ペアの登録および参照に責任を持つ。一般的に、アプリケーションモジュールは、自分の View をRegionViewRegistory インスタンスを利用して、 Initialize メソッドで登録する。

EmployeeListViewLeftRegion EmployeeModule モジュールの ModuleInit クラスの Initialize メソッドで登録する例。

this.regionManager.RegisterViewWithRegion( RegionNames.LeftRegion,
                                  () => this.container.Resolve());

Prism ライブラリ のRegionViewRegistry クラスの RegisterViewWithRegion メソッドは、Region名とViewを結びつけて登録するのに利用される。このメソッドを利用するには2つの方法がある。

  • RegionViewRegistory を直接利用する
  • RegionManager インスタンスを利用する(簡単にRegionViewRegistoryクラスにアクセスできる様に拡張メソッドが用意されている)

RegionManager の拡張メソッドは簡単にアクセスするために存在しており、View と Region Manager のインスタンスを登録することはできない。Regionを特定の名前で生成した場合は、Scope付き Region Managerかに関わらず登録され、View はそこに差し込まれる。

RegisterViewWithRegion メソッドは、2つのオーバーロードを持っている

  • RegisterViewWithRegion(string regionName, Type viewType);
  • RegisterViewWithRegion(string regionName, Func<object> getContentDelegete);

Viewを直接登録したい場合、最初のオーバーロードを利用する。”presenter first” または、”ViewModel-first” アプローチにおいて、Viewの生成に責任を持つプレゼンターを解決するデリゲートをInitializeメソッドで提供したい場合などは、2つめのオーバーロードを利用する。

最初のオーバーロードを使用した場合は、Region が生成されたとき、結びつけられたView を登録された中から探す。一致したViewが引っ張り出され、Regionの中にロードされる。新しいViewのインスタンスは、Service Locator を使って生成される。

View 間で Context を共有する

プロパティが接続されたRegionContext は、context を 親View と親Viewがホストする子Viewとで共有したい場合、便利である。この接続されたプロパティは、シンプルか複雑かに関わらずオブジェクトを保持できる。

UI 合成のサンプルにおいて、RegionContext は、選択された従業員IDを ProjectListView に受け渡し、Viewに、従業員が従事しているプロジェクトを表示するのに利用される。

EmployeeSummaryView.xmal ファイルでの例

<sdk:TabControl Grid.Row="1" 
                AutomationProperties.AutomationId="EmployeeSummaryTabControl" 
                Margin="8"
                prism:RegionManager.RegionName="TabRegion"
                prism:RegionManager.RegionContext="{Binding CurrentEmployee}"
                Width="Auto" Height="Auto" HorizontalAlignment="Stretch">
</sdk:TabControl>

Viewで、RegionContext を取得するために、GetObservableContext スタティックメソッドが RegionContext クラスで使われる。これは、Viewにパラメータを渡し、Value プロパティにアクセスすることができる。

EmployeeDetailsView.xaml.cs

employeeDetailsViewModel.CurrentEmployee = 
     RegionContext.GetObservableContext(this).Value as Employee; 

RegionContext の値は、新しい値を Value プロパティに設定することで簡単に変更できる。RegionContext プロパティが変更されたことも、イベントを購読することで検知できる。

EmployeeDetailsView.xmal.cs

RegionContext.GetObservableContext(this).PropertyChanged += (s, e)
                    =>
                    employeeDetailsViewModel.CurrentEmployee =
                    RegionContext.GetObservableContext(this).Value
                    as Employee;

DataContext プロパティは、Context の共有に利用できない。なぜなら、DataContext プロパティは、一般的に、View に対する、View Model を保持するのに利用されるため。

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です