Home > C# > Toolkit > UIパターン > Prism > Prismドキュメント > Prism 6

WPFのためのPrism Libraryを使用するナビゲーション

新規作成日 2017-11-23
最終更新日

原文「Navigation Using the Prism Library for WPF

ユーザーが、高機能なクライアント・アプリケーションと相互作用すると、そのユーザー・インターフェイス(UI)は、ユーザーが作業している、現在のタスクとデータを反映するために、連続的に更新されるでしょう。ユーザーが、アプリケーション内で、相互作用し、そして、さまざまなタスクを完了すると、UIは、ゆっくり時間をかけて、かなりの変更を受けるかもしれません。アプリケーションが、これらのUIの変更を調整する工程は、多くの場合、ナビゲーションとして参照されます。このトピックは、Prismライブラリを使用して、複合Model-View-ViewModel(MVVM)アプリケーションのためのナビゲーションを実装する方法について説明します。

頻繁に、ナビゲーションは、他のコントロールが追加される間、UIが削除される、一定のコントロールを示しています。他の場合には、ナビゲーションは、1つ以上の既存のコントロールの視覚的な状態が更新されたことを示しているかもしれません。-例えば、いくつかのコントロールは、他のコントロールが、表示されるか、あるいは、展開されるしている間、単純に隠される、あるいは、折りたたまれるかもしれません。同様に、ナビゲーションは、コントロールが、アプリケーションの現在の状態を反映するために、更新されることで、データが表示されていることを示すかもしれません。-例えば、master-detailの筋書きで、詳細ビューの中で表示されるデータは、マスターView内で、現在選択された項目に基づいて更新されます。ユーザー・インターフェイスが、ユーザーの現在のタスクとアプリケーションの現在の状態を反映するために更新されるため、これらの筋書きの全ては、ナビゲーションと見なすことができます。

アプリケーション内のナビゲーションは、(Mouseイベントや他のUIのジェスチャーを通して)UIで、ユーザーの対話から、あるいは、内部ロジックの状態変化の結果として、アプリケーション自体から、結果として生じることができます。場合によっては、ナビゲーションは、極めて簡単な、カスタム・アプリケーション・ロジックを必要としないUIの更新を含んでいるかもしれません。他の場合には、アプリケーションは、特定のビジネス・ルールが適用されているか確認することをプログラム的に制御するために、ナビゲーションに、複雑なロジックを実装しているかもしれません。-例えば、アプリケーションによっては、データ入力が正しいか、最初にユーザーが確認しないと特定のフォームから移動できない場合があります。

Windows Presentation Foundation (WPF)アプリケーションでは、直接、ナビゲーションのためのサポートを提供しているため、多くの場合、必要となるナビゲーションの動作を実装することは比較的簡単です。しかしながら、ナビゲーションは、Model-View-ViewModel(MVVM)パターンを使用するアプリケーションにおいて、あるいは、複数の疎く結合したモジュールを使用する複合アプリケーションで、実装することが、より複雑になる可能性があります。Prismでは、このような状況で、ナビゲーションを実装するための案内を提供します。

Navigation in Prism

ナビゲーションは、アプリケーションのユーザー相互作用、あるいは、内部のアプリケーションの状態の変更の結果として、アプリケーションの調整は、そのUIに変更するプロセスとして、定義されます。

UIの更新は、アプリケーションのビジュアル・ツリーから要素を追加するか、削除することによって、あるいは、ビジュアル・ツリー内の状態を、既存の要素に変更する適用をすることで、達成できます。WPFは、極めて柔軟な基盤で、多くの場合、このアプローチを使用して、個々のナビゲーション・シナリオを実装可能です。しかしながら、アプローチは、複数の要因に依存して、あなたのアプリケーションのために、最も最適でしょう。

Prismは、先に説明した、ナビゲーションの2つのスタイルを区別します。既存のコントロールに状態変化を通して、ビジュアル・ツリーで達成されるナビゲーションは、状態に基づいたナビゲーションとして参照されます。ビジュアル・ツリーから、要素の追加や削除を通して達成されるナビゲーションは、ビューに基づいたナビゲーションとして参照されます。Prismでは、アプリケーションが、プレゼンテーション・ロジックから(Viewにカプセル化される)UIと(View Modelにカプセル化される)データを分離するために、Model-View-ViewModel(MVVM)パターンを使用する場所に事例に焦点を当て、スタイルとナビゲーションの両方の実装上の案内を提供します。

状態に基づいたナビゲーション

State-Based Navigation

状態に基づいたナビゲーションにおいて、UIを表現するビューは、ビューそれ自身の中のViewModel内の状態の変化を通して、あるは、ユーザーの相互作用を通して、更新します。ナビゲーションのこのスタイルでは、ビューを他のビューに置き換える代わりに、ビューの状態が、変更されます。どのように、ビューの状態が変更されるかによって、更新されたUIは、ユーザーが、ナビゲーションのように感じるかもしれません。

このナビゲーションのスタイルは、次の状況では適切です。:

  • ビューは、異なるスタイルやフォーマットに、同じデータや機能を表示する必要があります。
  • ビューは、ViewModelの基盤となる状態に基づいて、そのレイアウトやスタイルを変更する必要があります。
  • ビューは、ビューのコンテクスト内で、ユーザーとの制限されたモーダルや非モーダルの相互作用を開始する必要があります。

このスタイルのナビゲーションは、UIが、ユーザーごとに異なるデータを表示する必要がある状況では、あるいは、ユーザーが、別のタスクを実行する必要があるときには、適切していません。これらの状況では、このトピックで、後ほど説明されるように、データやタスクを表示するために、分離したView(そして、View Model)を実装すること、そして、その次に、それらの間で、Viewに基づいたナビゲーションを使用して移動することを、お勧めします。同様に、ナビゲーションのこのスタイルは、実装するために、大量にUIの状態を変更する必要がある場合、ビューの定義を維持することが、大規模で困難になるため、ナビゲーションは、あまりにも複雑になり適切ではありません。この場合、ビューに基づいたナビゲーションを使用することにより、分離したビュー全体で、ナビゲーションを実装することをお勧めします。

次のセクションでは、状態に基づいたナビゲーションが使用できる、代表的な状況について説明します。これらの項目の各々は、インスタントメッセージングを実装する、状態に基づいたナビゲーションのQuickStartを参照します。-ユーザーが管理し、その連絡先と話すことができるスタイルのアプリケーション。

次のセクションでは、状態に基づいたナビゲーションが使用できる、代表的な状況について説明します。これらの項目の各々は、インスタントメッセージングを実装する、状態に基づいたナビゲーションのQuickStartを参照します。-ユーザーが管理し、その連絡先と話すことができるスタイルのアプリケーション。

Displaying Data in Different Formats or Styles

あなたのアプリケーションは、多くの場合、ユーザーに、同じデータを、別の形式やスタイル内に表示する必要があるかもしれません。 この場合、潜在的に、それらの間に、アニメーション化された移行を使用して、あなたは、ビュー内の、異なるスタイルの間で切り換えるために、状態に基づいたナビゲーションを使用することができます。例えば、状態に基づいたナビゲーションのQuickStartは、連絡先を、どのように、表示するか選択できます。-簡単なテキストのリスト、あるいは、アバター(アイコン)として、ユーザーは、ListボタンやAvatarsボタンをクリックすることで、これらの外観の表現の間で切り換えることができます。次の図に示すように、ビューは、2つの表示の間で、アニメーション化された移行を提供します。

状態に基づいたナビゲーションのQuickStartの連絡先ビュー・ナビゲーション

状態に基づいたナビゲーションのQuickStartの連絡先ビュー・ナビゲーション

なぜなら、別の外観の表現で、Viewは、同じデータを表示していますが、ViewModelは、表示の間で、ナビゲーションに関与する必要はありません。 この場合、ナビゲーションは、ビューそれ自身の中で、完全に、処理されます。このアプローチは、多くの柔軟性と一緒に、デザインするために、アプリケーション・コードの変更を必要とすることなく、非常に魅力的なユーザー・エクスペリエンスをUIデザイナーで提供します。

Blendのビヘイビアは、優れた方法で、ビュー内に、このナビゲーションのスタイルを実装できます。状態に基づいたナビゲーションのクイックスタート・アプリケーションは、アイコンとして連絡先を表示するためのリストと1つのボタンとして、連絡先を表示する1つのボタンのVisual状態マネージャーを使用して定義される2つの表示状態の間で切り換えるためのラジオボタンにBlendのDataStateBehaviorデータ結合を使用します。

<ei:DataStateBehavior Binding="{Binding IsChecked, ElementName=ShowAsListButton}" 
            Value="True"
            TrueState="ShowAsList" 
            FalseState="ShowAsIcons"/>

ユーザーが、ContactsやAvatarラジオボタンをクリックして、外観の状態は、ShowAsList表示状態とShowAsIcons表示状態の間で切り換えられます。また、これらの状態の間の反転する移行アニメーションは、Visual状態マネージャーを使用して、定義されます。

ユーザーが、詳細ビューを、現在選択された連絡先に切り換えるとき、ナビゲーションの、このスタイルの他の例は、状態に基づいたナビゲーションのQuickStartアプリケーションによって示されています。次に示す図は、この例を示しています。

状態に基づいたナビゲーションのQuickStartの連絡先の詳細ビュー

再び、これは、Blend DataStateBehaviorを使用して、簡単に実装することができます。;しかしながら、ここでは、それは、ShowDetailsとShowContactsの間で、反転する移行アニメーションを使用して、表示状態を切り換えるViewModel上のShowDetailsプロパティに結合されます。

反転しているアプリケーションの状態

Reflecting Application State

同様に、アプリケーション内のビューは、ときどき、内部のアプリケーション状態に変更に基づいて、交替でそれは、ViewModel上のプロパティで、表現される、そのレイアウトやスタイルを変更する必要があるかもしれません。このシナリオの例では、ユーザーの接続状態は、ConnectionStatusプロパティを使用して、Chat View Modelクラスで表現される状態に基づいたナビゲーションのQuickStartで示されています。ユーザーの接続状態が変化すると、次の図に示すように、ビューは、視覚的に、適切に現在の接続状態を表示する、ビューを提供して、(プロパティ変更通知イベントを通して)知らせます。

状態に基づいたナビゲーションのQuickStartの接続状態を表現します。

これを実装するには、ビューは、DataStateBehaviorデータが、適切な外観の状態の間で、切り換えるために、ViewModelのConnectionStatusプロパティを結合することを定義します。

接続状態が、ユーザーが、UIを経由して、あるいは、いくつかの内部のロジックやイベントに応じて、アプリケーションによって、変更できることに注意します。例えば、アプリケーションは、ユーザーが、一定の期間内に、ビューと対話しない場合、あるいは、ユーザーのカレンダーが、彼/彼女が会議中であることを示すとき、「利用できない」状態へ移動するかもしれません。状態に基づいたナビゲーションのQuickStartは、タイマーを使用して、ランダムに接続状態を切り換えることで、このシナリオをシミュレーションします。接続状態が、変更される時、ViewModel上のプロパティは、更新され、そして、ビューは、プロパティ変更イベントを通して、知らせます。UIは、続いて、現在の接続状態を反映するために、更新されます。

前述の全ての例は、ビューとユーザーの相互作用、あるいは、プロパティ内で変更を通して、ViewModelで定義する結果として、ビューの中で、そして、それらの間で切り替える、外観の状態の定義が含まれています。このアプローチは、UIデザイナーが、アプリケーション・コードに、ビューを置き換える必要も、あるいは、どんなコードの変更をする必要もなく、ビューで、ナビゲーションのような外観のビヘイビアを実装できます。ビューが、異なるスタイルやレイアウトで、同じデータをレンダリングすることを求められるとき、このアプローチは、適切です。それは、ユーザーが、別のデータやアプリケーション機能を表示する、あるいは、アプリケーションの異なる部分に移動するときの状況には適していません。

ユーザーと相互作用する

Interacting With the User

頻繁に、アプリケーションは、限られた方法で、ユーザーと相互作用する必要があるでしょう。これらの状況では、それは、多くの場合、新しいビューに移動する代わりに、現在のビューのコンテクスト内で、ユーザーと相互作用するために、より適切です。例えば、状態に基づいたナビゲーションのQuickStartでは、Send Messageボタンをクリックすることによって、ユーザーは、メッセージを連絡先に送信することができます。次の図に示すように、ビューは、続いて、ユーザーが、メッセージを入力するのを提供するポップアップウィンドウを表示します。ユーザーとこの相互作用が制限されるため、そして、論理的に、親のビューのコンテクストの範囲内で実行し、状態に基づいたナビゲーションとして、簡単に実装されることができます。

ユーザーとの相互作用は、状態に基づいたナビゲーションのQuickStartのポップアップウィンドウを使用します。

状態に基づいたナビゲーションのQuickStartの中で、ポップアップウィンドウを使用して、ユーザーと対話します。この動作を実装するには、状態に基づいたナビゲーションのQuickStartは、Send Messageボタンに結合したSendMessageコマンドを実装しています。このコマンドが、呼び出されるとき、ViewModelは、ポップアップウィンドウを表示するために、ビューと対話します。これは、MVVMパターンを実装する際に、説明した対話要求パターンを使用して達成されます。

次のコード例は、状態に基づいたナビゲーションのQuickStartアプリケーションのビューが、ViewModelにより提供される、SendMessageRequest対話要求オブジェクトに、どのように、反応するかを示します。要求イベントを受け取ると、SendMessageChildWindowが、ポップアップウィンドウとして表示されます。

ビューに基づいたナビゲーション

View-Based Navigation

状態に基づいたナビゲーションは、前に概要を述べたシナリオのために、便利ですが、アプリケーション内のナビゲーションは、最も頻繁に、アプリケーションのUI内で、1つのビューと一緒にもう一つを置き換えることによって、達成されます。Prismでは、ナビゲーションのこのスタイルは、ビューに基づいたナビゲーションとして参照されます。

アプリケーションの要求に応じて、この工程は、かなり複雑で慎重な調整を必要とすることがあります。多くの場合、ビューに基づいたナビゲーションを実装するとき、対処する必要がある、次のような共通の課題があります。:

  • ナビゲーションの目標-追加、あるいは、削除するための、ビューのコンテナやホスト・コントロール-ビューが、追加、あるいは、削除、あるいは、それらは、異なる方法で、ナビゲーションを視覚的に表示するかもしれないので、それぞれにナビゲーションを取り扱うかもしれません。多くの場合、ナビゲーションの目標は、簡単なFrameやContentControlです。そして、移動されたビューは、これらのコントロール内で単純に表示されます。しかしながら、ナビゲーション操作のための目標が、TabControlやListBoxコントロールのような、コンテナ・コントロールの異なる型である、多くのシナリオがあります。これらの場合では、ナビゲーションは、特別な方法で、既存のビューや新しいビューのアクティブ化、あるいは、選択する必要があるかもしれません。
  • また、アプリケーションは、多くの場合、ビューの移動を、どのように、確認するかを定義する必要があります。例えば、webアプリケーションでは、移動されるページは、多くの場合、直接、統一リソース識別子 (URI)で、識別されます。クライアント・アプリケーションでは、ビューは、タイプ名、リソース位置、あるいは、いろいろな異なる方法によって、識別することができます。その上さらに、複合アプリケーションでは、ビューは、多くの場合、分離したモジュールで定義される、疎く結合したモジュールから構成されます。それぞれのビューは、モジュール間で密接な結合と依存関係を導入しない方法で、識別する必要があります。
  • ビューが、識別されたあと、新しいビューをインスタンス化して初期化する工程を注意深く調整する必要があります。これは、MVVMパターンを使用するとき、特に重要です。この場合、ViewとView Modelは、ナビゲーション操作の間、ビューのデータ・コンテクストを経由し、それぞれ、インスタンスを生成し、そして、関連付ける必要があるかもしれません。その場合は、アプリケーションが、Unityアプリケーション・ブロック(Unity)や拡張管理フレームワーク(MEF)のような、依存関係注入コンテナを活用しているとき、ビューのインスタンス生成、と/あるいは、ViewModel(そして、他のに依存したクラス)は、特定の構築の仕組みを使用して、達成する必要があります。
  • MVVMパターンは、アプリケーションUIとそのプレゼンテーション間とビジネス・ロジックの分離を提供します。しかしながら、アプリケーションのナビゲーションのビヘイビアは、多くの場合、アプリケーションのUIとプレゼンテーション・ロジック部品に及びます。ユーザーは、多くの場合、ビュー内からナビゲーションを開始するでしょう。そして、ビューは、そのナビゲーションの結果として更新されますが、ナビゲーションは、また、ViewModel内から、初期化、あるいは、調整する必要があります。アプリケーション全体にわたって、ViewとView Modelのナビゲーションの動作を明確に分離する能力は、考慮すべき重要な測面です。
  • また、アプリケーションは、多くの場合、それが、適切に初期化できるように、ビューに、パラメータやコンテキストを渡す必要があります。例えば、ユーザーが、特定の顧客の詳細を更新するために、ビューに移動する場合、顧客のIDやデータは、ビューに渡される必要があるため、それは、正しい情報を表示することができます。
  • また、多くのアプリケーションは、ナビゲーションを確実に行うために、一定のビジネス・ルールに従い注意深く調整する必要があります。例えば、ユーザーは、ビューから、わきへ移動する前に、促されるかもしれません。それは、そのビューの中で作成されている、どんな無効なデータでも修正する、あるいは、どんなデータ変更も送信する、あるいは、破棄することを促すことができます。この工程は、先程のビューと新しいビューの間に、注意深い調整を必要とします。
  • 最後に、ほとんどの近代的なアプリケーションは、ユーザーが、簡単に、前に表示されたビューに、戻す(あるいは、進めます)移動ができます。同様に、いくつかのアプリケーションでは、タスクが完了し、そして、一度に、それらのすべての変更を送信する前に、一連のビューやフォ-ムを使用して、それらの作業の流れを実装し、そして、ユーザーが、それらを通して、データを追加し、あるいは、更新し、前方へ、あるいは、後ろに移動できます。これらのシナリオは、いくつかの種類の更新履歴(あるいは、履歴)の仕組みを必要とし、それは、ナビゲーションの配列が格納されることができるように、再生、あるいは、事前に定義されました。

Prismは、ナビゲーションをサポートする、Prism領域メカニズムを拡張することによって、これらの難問のためのサポートと案内を提供します。 次の項目は、Prismの領域の概要を提供し、そして、ビューに基づいたナビゲーションをサポートするために、それらが、どのように、拡張されたかについて説明します。

Prismの領域の概要

Prism Region Overview

Prismの領域は、疎く結合した方法で、構築するために、アプリケーションの総合的なUIを提供することで、複合アプリケーションの開発をサポートするように設計されています(すなわち、アプリケーションは、複数のモジュールから構成されています)。領域は、アプリケーションUIの中に示されるモジュールに、アプリケーションの総合的なUIの構造についての明示された知識を持つためのモジュールを必要とする事無く、ビューを定義できます。それらは、モジュール自体に変更を必要とすることなく、それによって、UIデザイナーは、アプリケーションのために、最も適切なUIデザインとレイアウトを選択できる、アプリケーションのUIの配置を簡単に変更できます。

Prismの領域は、基本的には、ビューが、表示されることができる、プレースホールダーに名をつけられます。アプリケーションUIのどんなコントロールでも、ここに、示されるように、RegionName添付プロパティを、単純に、それに加えることによって、領域を宣言することができます。:

<ContentControl prism:RegionManager.RegionName="MainRegion" ... />

領域として指定された、それぞれのコントロールのために、Prismは、領域とRegionAdapterオブジェクトを表示するために、指定のコントロールに、ビューの配置とアクティブ化を管理するRegionオブジェクトを作成します。Prism Libraryは、ほとんどの一般的なWPFコントロールのための、RegionAdapter実装を提供します。あなたが、追加のコントロールをサポートする、あるいは、カスタム・ビヘイビアを定義する必要があるとき、カスタムRegionAdapterを作成することができます。RegionManagerクラスは、アプリケーションの内のRegionオブジェクトへ、アクセスを提供します。

多くの場合、領域コントロールは、ContentControlのような、単純なコントロールです。それは、一度に、1つのビューを表示することができます。 他の場合には、Regionコントロールは、同時に、TabControlやListBoxコントロールのような、複数のビューを表示することができるコントロールです。

領域アダプタは、関連する領域内のビューのリストを管理します。これらのビューの1つ以上は、その定義されたレイアウト戦略に従って、領域コントロールに表示されます。ビューは、後で、そのビューを取得するために使用することができる、名前を割り当てられることができます。領域アダプタは、領域の中のビューのアクティブ状態を管理します。アクティブ・ビューは、選択された、あるいは、一番上のビューです。-例えば、TabControlでは、アクティブ・ビューが、選択されたタブに表示されます。;ContentControlでは、アクティブ・ビューが、現在、コントロールの内容として表示されているビューです。

備考: ビューのアクティブ状態は、ナビゲーションの間に検討するために重要です。頻繁に、あなたは、アクティブ・ビューが、ユーザーが、それから、わきへ移動する前にデータを保存できる、あるいは、それは、ナビゲーション操作を確認やキャンセルできるナビゲーションに関与することを望むでしょう。

Prismの以前のバージョンは、2つの方法で領域内に、ビューを表示できました。はじめに、ビューを、プログラム上の領域内に表示できるビュー注入が、呼び出されます。このアプローチは、アプリケーションのプレゼンテーション・ロジックに従って、ビューが、たびたび変更する領域に表示される動的なコンテンツのために、役に立ちます。

ビュー注入は、RegionクラスのAddメソッドによってサポートされています。次のコード例は、あなたが、どのように、RegionManagerクラスを通じてRegionオブジェクトに参照を取得するか、あるいは、それにプログラム的にビューを追加するかを示します。この例では、ビューは、依存関係注入コンテナを使用して作成されます。

    IRegionManager regionManager = ...;
    IRegion mainRegion = regionManager.Regions["MainRegion"];
    InboxView view = this.container.Resolve<InboxView>();
    mainRegion.Add(view);

View発見と呼ばれる、2つ目のメソッドは、領域名に対して、ビューの型をモジュールを登録できます。指定された名前で、領域が表示される時はいつでも、指定されたViewのインスタンスは、自動的に作成され、そして、領域内に表示されるでしょう。このアプローチは、領域に表示されるビューが、変更されない、比較的、静的内容のために、役に立ちます。

View発見は、RegionManagerクラスのRegisterViewWithRegionメソッドによってサポートされています。このメソッドは、あなたが、名前を付けた領域が表示されるとき、呼び出されるコールバック・メソッドを指定することができます。次のコード例は、中心となる領域が、最初に表示されるとき、あなたが、(依存関係注入コンテナによって)どのようにビューを作成することができるかを示します。

    IRegionManager regionManager = ...;
    regionManager.RegisterViewWithRegion("MainRegion", () =>
                       container.Resolve<InboxView>());

ビュー注入と発見を使用して、Prismの領域サポートの詳細な概要とアプリケーションUIを構成するために、どのように、領域を活用するかについての情報については、ユーザー・インターフェイスを構成するを参照してください。このトピック残りで、ビューに基づいたナビゲーションをサポートするために、領域がどのように、拡張されたか、そして、前述の様々な課題に、どのように、対処するか、について説明します。

基本的な領域ナビゲーション

Basic Region Navigation

ビュー注入とビュー発見の両方は、ナビゲーションの限定された型式で考えることができます。-ビュー注入は、プログラムによるナビゲーションの明示された型式です。そして、View発見は、暗黙、あるいは、遅延ナビゲーションの型式です。しかしながら、Prism 4.0では、領域は、URIと拡張可能なナビゲーションの仕組みに基づいて、ナビゲーションのより一般的な概念をサポートするために拡張されました。

領域内のナビゲーションは、新しいビューが、その領域内で表示されることを示します。表示されるビューは、既定で、作成されるビューの名前を参照する、URIによって識別されます。あなたは、INavigateAsyncインターフェイスによって定義されるRequestNavigateメソッドを使用して、ナビゲーションをプログラム的に開始することができます。

備考: その名前にもかかわらず、INavigateAsyncインターフェイスは、分離したバックグラウンド・スレッドで実行される、非同期ナビゲーションを表示しません。その代わりに、INavigateAsyncインターフェイスは、擬似非同期ナビゲーションを実行する機能で表示します。RequestNavigateメソッドは、ユーザーが、ナビゲーションを確認する必要がある場合のように、ナビゲーション操作を完了した後に、同期して返す、あるいは、それは、ナビゲーション操作が、まだ保留している間に、帰すかもしれません。ナビゲーションの間に、あなたが指定するコールバックと継続を指定することで、Prismは、バックグラウンド・スレッド上で移動する複雑さを必要とせずに、これらのシナリオを有効にする仕組みを提供しています。

INavigateAsyncインターフェイスは、あなたが、その領域内で、ナビゲーションを開始することができる、Regionクラスによって実装されています。

IRegion mainRegion = ...;
mainRegion.RequestNavigate(new Uri("InboxView", UriKind.Relative));

また、あなたは、RegionManager上で、あなたが、移動するために、領域の名前を指定できるRequestNavigateメソッドを呼び出すことができます。 前述のコード例で示すように、この便利なメソッドは、指定の領域の参照を取得し、そして、RequestNavigateメソッドを呼び出します。

IRegionManager regionManager = ...;
regionManager.RequestNavigate("MainRegion",
                                new Uri("InboxView", UriKind.Relative));

既定では、ナビゲーションのURIは、コンテナで登録されるビューの名前を指定します。

MEFを使用して、あなたは、単純に、指定された名前でビュー型をエクスポートすることができます。

[Export("InboxView")]
public partial class InboxView : UserControl { ... }

ナビゲーションの間、指定されたViewは、コンテナやMEFによって、その対応するViewModelと他のものに依存したサービスとコンポーネントと一緒に、インスタンスを生成します。ビューが、インスタンスを生成したあと、それは、続いて、指定された領域に追加され、アクティブにされます。 (アクティブ化は、このトピック後半で詳しく記述されています)。

備考 前述の説明は、URIが、コンテナとして、エクスポート、あるいは、登録されるビュー型の名前を参照する、ビュー優先ナビゲーションを説明しています。ビュー優先ナビゲーションでは、依存したViewModelは、ビューの依存関係として作成されます。他のアプローチは、ViewModelを使用することです。-ナビゲーションURIが、View Model型の名前を参照する最初のナビゲーションは、コンテナでエクスポート、あるいは、登録されます。 View models.-ビューが、データ・テンプレートとして、定義されるとき、あるいは、あなたが、ナビゲーション・スキームが、ビューと独立して定義されることを望むとき、最初のナビゲーションが、役に立ちます。

また、RequestNavigateメソッドは、あなたが、ナビゲーションが完了すると、呼び出される、コールバック・メソッドやデリゲートを指定することができます。

private void SelectedEmployeeChanged(object sender, EventArgs e)
{
    ...
    regionManager.RequestNavigate(RegionNames.TabRegion,
                        "EmployeeDetails", NavigationCompleted);
}
private void NavigationCompleted(NavigationResult result)
{
    ...
}

NavigationResultクラスは、ナビゲーション操作についての情報を提供する、プロパティを定義します。Resultプロパティは、ナビゲーションが成功したかどうか示しています。ナビゲーションが、成功した場合、Resultプロパティは、trueです。ナビゲーションが、機能しない場合、IConfirmNavigationResult.ConfirmNavigationRequestメソッドでは、通常は、'continuationCallBack(false)'を返すため、Resultプロパティは、falseです。ナビゲーションが、例外のために機能しない場合、Resultプロパティは、falseです。そして、Errorプロパティは、ナビゲーション中に投げられる、何らかの例外への参照を提供します。Contextプロパティは、URIとそれに含まれるどんなパラメータ、そして、ナビゲーション操作を調整するナビゲーション・サービスへの参照でも、ナビゲーションへのアクセスを提供します。

ナビゲーションへのViewとView modelの参加

View and View Model Participation in Navigation

頻繁に、あなたのアプリケーションのViewとView Modelは、ナビゲーションに関与することを望みます。INavigationAwareインターフェイスは、これを有効にします。あなたは、Viewや(より一般には)ViewModelで、このインターフェイスを実装することができます。このインターフェイスを実装することによって、あなたのViewやViewModelは、ナビゲーション工程に関与するために、選択できます。

備考 以下の説明において、Viewとナビゲーションの間に、このインターフェイスを呼び出すために、参照が、作成されますが、INavigationAwareインターフェイスが、Viewによって、あるいは、ViewModelによって、実装されるかどうかに関係なく、ナビゲーションの間、呼び出されることに注意する必要があります。ナビゲーションの間、Prismは、INavigationAwareインターフェイスを実装しているかどうか確認します。;それを行う場合、それは、ナビゲーションの間、必要とされるメソッドを呼び出します。また、Prismは、このインターフェイスを実装するViewのDataContextとして、オブジェクトが設定されているか、確認します。;その場合、それは、ナビゲーションの間、必要とされるメソッドを呼び出します。

このインターフェイスは、ナビゲーション操作に関与するために、ViewやView Modelを提供します。INavigationAwareインターフェイスは、3つのメソッドを定義します。

public interface INavigationAware
{
    bool IsNavigationTarget(NavigationContext navigationContext);
    void OnNavigatedTo(NavigationContext navigationContext);
    void OnNavigatedFrom(NavigationContext navigationContext);
}

IsNavigationTargetメソッドは、ナビゲーションの要求を取り扱うことができるかどうかにかかわらず、既存の(表示した)ViewやView Modelを示すことができます。これは、あなたが、ナビゲーション操作を取り扱うために、既存のビューを再利用できる場合、あるいは、すでに存在する、Viewに移動するとき、役に立ちます。例えば、Viewに表示されている利用者の情報は、異なる顧客の情報を示すために、更新できます。このメソッドを使用するための詳細については、このトピックの後半で、既存のビューに移動するの項目を参照してください。

OnNavigatedFromとOnNavigatedToメソッドは、ナビゲーション操作の間、呼び出されます。領域内の現在アクティブ・ビューが、このインターフェイス(やそのViewModel)を実装する場合、そのOnNavigatedFromメソッドは、ナビゲーションが実行される前に、呼び出されます。OnNavigatedFromメソッドは、先程のビューを、どんな状態でも保存、あるいは、そのアクティブ化の解除や削除のために備えることができます。例えば、どんな変更でも保存するために、ユーザーは、Webサービスやデータベースを作成します。

新たに作成されたViewが、このインターフェイス(やそのViewModel)を実装する場合、ナビゲーションが、完了した後、そのOnNavigatedToメソッドが呼び出されます。OnNavigatedToメソッドは、それ自体を初期化するために、場合によっては、どんなパラメータでも使用して、それにナビゲーションURIを渡し、新たに表示されたViewを提供します。詳細については、次のナビゲーションの間に、パラメータ受渡すの項目を参照してください。

新しいViewが、インスタンスを生成し、初期化され、そして、対象とする領域に追加されたあと、それは、続いて、アクティブ・ビューになり、そして、以前のビューは非アクティブになります。時には、あなたは、非アクティブのViewが、領域から削除されることを望みます。Prismは、あなたは、非アクティブのViewが、領域から、あるいは、単純に、非アクティブとして、マークされることで、削除されるかどうかに関係なく、あなたが、指定することで、領域の中で、Viewの寿命を制御することができる、IRegionMemberLifetimeインターフェイスを提供します。

public class EmployeeDetailsViewModel : IRegionMemberLifetime
{
    public bool KeepAlive
    {
        get { return true; }
    }
}

IRegionMemberLifetimeインターフェイスは、1つの読取専用プロパティ(KeepAlive)を定義します。このプロパティが、falseを返すと、Viewは、非アクティブになる時、領域から削除されます。領域が、もはや、Viewに参照を持っていないため、それは、その後、ガベージ・コレクションの対象になります(あなたのアプリケーション内のいくつかの他のコンポーネントが、それへの参照を保持しない限り)。あなたは、あなたのViewやあなたのView Modelクラスで、このインターフェイスを実装することができます。IRegionMemberLifetimeインターフェイスは、あなたが、アクティブ化と非アクティブの間、領域の中で、Viewの寿命を管理することを主な目的としますが、また、KeepAliveプロパティは、新しいビューが、対象とする領域でアクティブにされたあと、ナビゲーションの間、考慮されます。

備考 ItemsControlやTabControlを使用するような、複数のビューを表示できる領域は、非アクティブで、アクティブ・ビューに表示するでしょう。 この種の領域から、非アクティブなViewの削除は、UIからViewが、結果として削除されるでしょう。

ナビゲーションの間に、パラメータ受渡す。

Passing Parameters During Navigation

あなたのアプリケーションで必要とされる、ナビゲーションのビヘイビアを実装するには、あなたは、多くの場合、ナビゲーション要求の間、現在、対象とするビュー名前より、追加のデータを指定する必要があります。NavigationContextオブジェクトは、ナビゲーションURI、そして、その中、あるいは、外部に指定する、どんなパラメータへのアクセスを提供します。あなたは、IsNavigationTarget、OnNavigatedFromとOnNavigatedToメソッドから、NavigationContextを呼び出すことができます。

Prismは、ナビゲーション・パラメータを指定する、そして、取得するのを助けるために、NavigationParametersクラスを提供します。NavigationParametersクラスは、各々のパラメータのための、名前-値の組み合わせのリストを保持します。あなたは、ナビゲーションURIやパッシング・オブジェクト・パラメータの一部として、パラメータを渡すために、このクラスを使用することができます。

次のコード例は、ナビゲーションURIに添付できるように、それぞれの文字列パラメータをNavigationParametersインスタンスに、どのように、追加するかを示します。

Employee employee = Employees.CurrentItem as Employee;
if (employee != null)
{
    var navigationParameters = new NavigationParameters();
    navigationParameters.Add("ID", employee.Id);
    _regionManager.RequestNavigate(RegionNames.TabRegion,
            new Uri("EmployeeDetailsView" + navigationParameters.ToString(), UriKind.Relative));
}

さらに、あなたは、NavigationParametersインスタンスに、それらを追加することによって、オブジェクト・パラメータを渡すことができます。そして、それを、RequestNavigateメソッドのパラメータとして、渡します。これは、次のコードで、示されています。

Employee employee = Employees.CurrentItem as Employee;
if (employee != null)
{
    var parameters = new NavigationParameters();
    parameters.Add("ID", employee.Id);
    parameters.Add("myObjectParameter", new ObjectParameter());
    regionManager.RequestNavigate(RegionNames.TabRegion,
            new Uri("EmployeeDetailsView", UriKind.Relative), parameters);
}

あなたは、NavigationContextオブジェクト上で、Parametersプロパティを使用して、ナビゲーション・パラメータを取得することができます。このプロパティは、それぞれのパラメータに、簡単なアクセスできるインディクサー・プロパティを提供するNavigationParametersクラスのインスタンスを返します。それらと独立して、問合せを通じて、あるいは、RequestNavigateメソッドを通して、渡されます。

public void OnNavigatedTo(NavigationContext navigationContext)
{
    string id = navigationContext.Parameters["ID"];
    ObjectParameter myParameter = navigationContext.Parameters["myObjectParameter"];
}

Navigating to Existing Views

頻繁に、これは、新しいViewで、置き換える代わりに、あなたのアプリケーション内のViewで、再利用、更新、あるいは、ナビゲーションの間で、アクティブ化するために、より適切です。これは、多くの場合、あなたが、同じ型のビューに移動しますが、ユーザーに、異なる情報や状態を表示する必要がある、あるいは、UIで適切なViewが、既に利用可能であるとき、あるいは、UIで適切なViewが、既に利用可能であるが、(つまり、選択するか、最上位で作成される)アクティブ化する必要がある場合です。

最初のシナリオの例については、あなたのアプリケーションは、ユーザーが、EditCustomer Viewを使用して、利用者の記録を編集できると想像します。そして、ユーザーは、現在、顧客ID 123を編集するために、そのViewを使用しています。顧客が、顧客ID 456の利用者の記録を編集することに決めた場合、ユーザーは、単純に、EditCustomer Viewに移動することができ、新しい顧客IDを入力することができます。EditCustomer Viewは、続いて、新しい顧客のためのデータを取得することができ、それに対応して、そのUIを更新します。

2つ目のシナリオの1つの例は、アプリケーションは、ユーザーが、一度に、1つ以上の利用者の記録を編集できる場所です。この場合、アプリケーションは、Tabコントロールで、複数のEditCustomer Viewインスタンスを表示します。-例えば、1つの顧客ID 123ともう1つの顧客ID 456。ユーザーが、EditCustomer Viewに移動し、そして、顧客ID 456を入力するとき、対応するViewは、アクティブにされるでしょう(つまり、その対応するタブが選択されます)。ユーザーが、EditCustomer Viewに移動し、そして、顧客ID 789を入力する場合、新しいインスタンスが、作成され、そして、Tabコントロールで表示されるでしょう。

既存のViewに移動するための機能は、いろいろな理由のための役に立ちます。多くの場合、それを同じ型の新しいインスタンスに置き換える代わりに、既存のViewを更新することは、より効率的です。同様に、重複するViewを作成する代わりに、既存のViewをアクティブにすることは、より整合性の取れた、ユーザー・エクスペリエンスを提供します。加えて、多くのカスタム・コードを必要とすることなく、アプリケーションが、より簡単に、開発し、そして、維持するために、継ぎ目なくこれらの状況を取り扱う能力を示します。

Prismは、INavigationAwareインターフェイス上で、IsNavigationTargetメソッドによって、以前に説明された、2つのシナリオをサポートしています。 このメソッドは、領域内のすべてのView上で、対象とするViewと同じ型のナビゲーション中に呼び出されます。前述の例で、Viewの対象とする型は、EditCustomer Viewです。それで、IsNavigationTargetメソッドは、現在の領域内で、全ての既存のEditCustomer Viewインスタンス上で、呼び出されます。Prismは、対象とする型の短い型の名前を想定する、ViewのURIから対象とする型を決定します。

備考: Prismは、対象とするViewの型を決定するために、ナビゲーションURIのViewの名前は、実際の対象とする型の短い型の名前と同じにする必要があります。例えば、あなたのViewが、MyApp.Views.EmployeeDetailsViewクラスによって、実装される場合、ナビゲーションURIで指定されたViewの名前は、EmployeeDetailsViewある必要があります。これは、Prismにより提供される既定の動作です。あなたは、カスタム・コンテンツ・ローダー・クラスを実装することによって、この動作をカスタマイズすることができます。;あなたは、IRegionNavigationContentLoaderインターフェイスを実装することで、あるいは、RegionNavigationContentLoaderクラスから派生することで、これを行うことができます。

IsNavigationTargetメソッドの実装は、ナビゲーションの要求を取り扱うことができるかに関係なく、決定するために、NavigationContextパラメータを使用することができます。NavigationContextオブジェクトは、ナビゲーションURIとナビゲーション・パラメータに、アクセスを提供します。前述の例で、EditCustomer View Model内のこのメソッドの実装は、ナビゲーションの要求の中で、現在の顧客IDと指定されたIDを比較します。そして、それらが、一致する場合、それは、trueを返します。

public bool IsNavigationTarget(NavigationContext navigationContext)
{
    string id = navigationContext.Parameters["ID"];
    return _currentCustomer.Id.Equals(id);
}

IsNavigationTargetメソッドが、常に、trueを返す場合、ナビゲーション・パラメータに関係なく、そのViewのインスタンスは、常に、再利用されます。これは、あなたが、個々の型の1つのViewが、個々の領域内に示されることを確認できます。

ナビゲーションを確認、あるいは、キャンセルします。

Confirming or Cancelling Navigation

あなたは、多くの場合、あなたが、ナビゲーション操作の間、ユーザーと相互作用する必要があることを見つけるでしょう。それで、ユーザーが、それを確認、あるいは、キャンセルできます。多くのアプリケーションでは、例えば、ユーザーは、データの入力や編集途中で、移動しようとするかもしれません。これらの状況では、彼/彼女が、ページから、移動を続ける前に、既に入力されているデータを保存する、あるいは、破棄することを望むかどうか、あるいは、ユーザーが、完全に移動操作をキャンセルすることを望むかどうかに関係なく、ユーザーに尋ねるといいかもしれません。Prismは、IConfirmNavigationRequestインターフェイスにより、これらのシナリオをサポートしています。

IConfirmNavigationRequestインターフェイスは、INavigationAwareインターフェイスから派生します。そして、ConfirmNavigationRequestメソッドを追加します。あなたのViewやView Modelクラスで、このインターフェイスを実装することによって、ある意味では、あなたは、ユーザーと相互作用できる、ナビゲーションの流れに関与できます。それで、ユーザーが、ナビゲーションを確認、あるいは、キャンセルできます。あなたは、多くの場合、高等なMVVMの筋書きで説明されるように、確認ポップアップ・ウィンドウを表示するために、Interaction Requestオブジェクトを使用します。

備考: ConfirmNavigationRequestメソッドは、先に説明したOnNavigatedFromメソッドと同様に、アクティブViewやView Modelで呼び出されます。

ConfirmNavigationRequestメソッドは、先ほど説明した現在のナビゲーション・コンテキストへの参照、そして、あなたが、ナビゲーションが継続することを望むとき、呼び出すことができるコールバック・メソッドの2つのパラメータを提供します。この理由のため、コールバックは、継続コールバックとして知られています。あなたは、継続コールバックに、参照を格納することができ、アプリケーションは、ユーザーとの相互作用が完了したあと、それを呼び出すことができます。あなたのアプリケーションが、Interaction Requestオブジェクトによって、ユーザーと相互作用する場合、あなたは、継続コールバックに、対話要求から、コールバックへの呼び出しを連結することができます。次の図は、全体の工程を示しています。

次の手順は、InteractionRequestオブジェクトを使用して、ナビゲーションを確認する工程をまとめてます。:

  1. ナビゲーション操作は、RequestNavigate呼び出しを通して開始します。
  2. ViewやView Modelが、IConfirmNavigationを実装する場合、ConfirmNavigationRequestを呼び出します。
  3. ViewModelは、対話要求イベントを発生させます。
  4. Viewは、確認ポップアップ・ウィンドウを表示して、ユーザーの応答を待ちます。
  5. ユーザーが、ポップアップ・ウィンドウを閉じると、対話要求コールバックが、呼び出されます。
  6. 継続コールバックは、保留中のナビゲーション操作を継続、あるいは、キャンセルするために、呼び出されます。
  7. ナビゲーション操作は、完了、あるいは、キャンセルされます。

これを説明するために、ビュー切り替えナビゲーションのQuick Startを見て下さい。このアプリケーションは、ComposeEmailViewとComposeEmailViewModelクラスを使用して、新しい電子メールを作成するユーザーのための機能を提供します。View Modelクラスは、IConfirmNavigationインターフェイスを実装しています。ユーザーが、移動する場合、Calendarボタンをクリックするような、電子メールを作成しているとき、ConfirmNavigationRequestメソッドは、呼び出され、View Modelは、ユーザーとナビゲーションを確認することができます。これに対応するために、次のコードの例に示すように、View Modelクラスは、対話の要求を定義します。

public class ComposeEmailViewModel : NotificationObject, IConfirmNavigationRequest
{
    . . .
    private readonly InteractionRequest<Confirmation> confirmExitInteractionRequest;

    public ComposeEmailViewModel(IEmailService emailService)
    {
        . . .
        this.confirmExitInteractionRequest = new InteractionRequest<Confirmation>();
    }

    public IInteractionRequest ConfirmExitInteractionRequest
    {
        get { return this.confirmExitInteractionRequest; }
    }
}

ComposeEmailViewクラスでは、対話の要求トリガが、定義され、データは、ViewModelの上で、ConfirmExitInteractionRequestプロパティに結合されます。対話の要求が、作成されるとき、簡単なポップアップウィンドウが、ユーザーに表示されます。

<UserControl.Resources>
    <DataTemplate x:Key="ConfirmExitDialogTemplate">
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
                    Text="{Binding}"/>
    </DataTemplate>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="White">
<ei:Interaction.Triggers>
        <prism:InteractionRequestTrigger SourceObject="{Binding  
            ConfirmExitInteractionRequest}">
        <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True"/>
        </prism:InteractionRequestTrigger>
</ei:Interaction.Triggers>
...

ユーザーが、電子メールを作成している間、移動したい場合、ComposeEmailVewModelクラスのConfirmNavigationRequestメソッドが、呼び出されます。このメソッドの実装は、以前に定義した対話の要求を呼び出します。そのため、ユーザーが、ナビゲーション操作を確認やキャンセルすることができます。

void IConfirmNavigationRequest.ConfirmNavigationRequest(
            NavigationContext navigationContext, Action<bool> continuationCallback)
{
    . . .
    this.confirmExitInteractionRequest.Raise(
                new Confirmation {Content = "...", Title = "..."},
                c => {continuationCallback(c.Confirmed);});
}

ユーザーが、操作のキャンセルを確認するための、確認ポップアップ・ウィンドウのボタンをクリックするとき、対話の要求のために、コールバックが、呼び出されます。このコールバックは、単純に、継続コールバックを呼び出します。Confirmedフラグの値に渡し、ナビゲーションを、継続、あるいは、キャンセルします。

備考: 対話要求イベントが発生した後、ConfirmNavigationRequestメソッドは、すぐに返され、ユーザーは、アプリケーションのUIと相互作用を継続することに注意する必要があります。ユーザーが、ポップアップウィンドウの上の、OKやCancelボタンをクリックすると、ナビゲーション操作を完了するために、順番に、継続コールバックを呼び出す、対話の要求のコールバック・メソッドが、作成されます。すべてのメソッドは、UIスレッドで呼び出されます。この手法を使用して、バックグラウンド・スレッドは、必要とされません。

この仕組みを使用して、あなたは、ナビゲーションの要求が、すぐに実行される、あるいは、延期される場合、ユーザーとの相互作用、あるいは、いくつかの他の非同期相互作用の保留を制御することができます。(例えば、webサービスリクエストの結果として)。ナビゲーションを前に進めることを、使用可能にするために、あなたは、単純に、継続コールバック・メソッドを呼び出すことができます。それが、継続できることを指示するために、trueを渡します。同様に、あなたは、ナビゲーションが、キャンセルされる必要があることを示すために、falseを渡すことができます。

void IConfirmNavigationRequest.ConfirmNavigationRequest(
            NavigationContext navigationContext, Action<bool> continuationCallback)
{
    continuationCallback(true);
}

あなたが、ナビゲーションを遅延したい場合、あなたは、ユーザー(またはWebサービス)との相互作用が完了するとき、あなたが、続いて、呼び出すことができる継続コールバックに、参照を格納することができます。あなたが、継続コールバックを呼び出すまで、ナビゲーション操作は、保留します。

ユーザーが、その間に、他のナビゲーション操作を開始する場合、ナビゲーションの要求は、続いて、キャンセルされます。この場合、それが、関連づけるナビゲーション操作が、もはや現行のものではないため、継続コールバックを呼び出しても、効果がありません。同様に、あなたが、継続コールバックを呼び出さないと決める場合、ナビゲーション操作が保留中になり、新しいナビゲーション操作に置き換えられます。

ナビゲーションの履歴を使用する

Using the Navigation Journal

NavigationContextクラスは、領域内の移動の間、一連の操作を調整するための役割を果たす、領域ナビゲーション・サービスへ、アクセスを提供します。それは、ナビゲーションが実行している領域へ、アクセスを提供し、そして、ナビゲーション履歴をその領域に関連付けます。領域ナビゲーション・サービスは、次のように定義されるIRegionNavigationServiceを実装しています。

public interface IRegionNavigationService : INavigateAsync
{
    IRegion Region {get; set;}
    IRegionNavigationJournal Journal {get;}
    event EventHandler<RegionNavigationEventArgs> Navigating;
    event EventHandler<RegionNavigationEventArgs> Navigated;
    event EventHandler<RegionNavigationFailedEventArgs> NavigationFailed;
}

領域ナビゲーション・サービスが、INavigateAsyncインターフェイスを実装するため、そのRequestNavigateメソッドを呼び出すことによって、あなたは、親の領域内で、ナビゲーションを開始することができます。ナビゲーション操作が開始するとき、Navigatingイベントが、呼び出されます。領域内のナビゲーションが完了するとき、Navigatedイベントが、発生します。移動の間、エラーと遭遇する場合、NavigationFailedは発生します。

Journalプロパティは、アクセスを、領域に関連したナビゲーションの履歴に提供します。ナビゲーション履歴は、次のように定義されているIRegionNavigationJournalインターフェイスを実装しています。

public interface IRegionNavigationJournal
{
    bool CanGoBack { get; }
    bool CanGoForward { get; }
    IRegionNavigationJournalEntry CurrentEntry { get; }
    INavigateAsync NavigationTarget { get; set; }
    void Clear();
    void GoBack();
    void GoForward();
    void RecordNavigation(IRegionNavigationJournalEntry entry);
}

あなたは、OnNavigatedToメソッドを呼び出しを通じて、ナビゲーションの間のView内で、領域ナビゲーション・サービスに参照を取得し、そして、格納することができます。既定では、Prismは、あなたが、領域の中で、前方、あるいは、後方へ移動できる、簡単なスタックに基づく履歴を提供します。

あなたは、Viewそのもの中から、ユーザーが移動するために、ナビゲーションの履歴を使用することができます。次の例では、ViewModelは、ホスト領域で、ナビゲーションの履歴を使用するGoBackコマンドを実装しています。その結果、Viewは、ユーザーが、領域の中で、簡単に、前のビューに戻って移動できる、Backボタンを表示することができます。同様に、あなたは、ウィザード・スタイルの作業の流れを実装するために、GoForwardコマンドを実装することができます。

public class EmployeeDetailsViewModel : INavigationAware
{
    ...
    private IRegionNavigationService navigationService;

    public void OnNavigatedTo(NavigationContext navigationContext)
    {
        navigationService = navigationContext.NavigationService;
    }

    public DelegateCommand<object> GoBackCommand { get; private set; }

    private void GoBack(object commandArg)
    {
        if (navigationService.Journal.CanGoBack)
        {
            navigationService.Journal.GoBack();
        }
    }

    private bool CanGoBack(object commandArg)
    {
        return navigationService.Journal.CanGoBack;
    }
}

あなたが、その領域内で、特定の作業の流れのパターンを実装する必要がある場合、あなたは、領域のためのカスタム履歴を実装することができます。

備考: ナビゲーションの履歴は、領域ナビゲーション・サービスで手配される領域に基づいたナビゲーション操作のため、1つだけ使用することができます。 あなたが、領域の中で、ナビゲーションを実装するために、View発見やView注入を使用する場合、ナビゲーションの履歴は、ナビゲーションの間、更新されないでしょう。そして、その領域の中で、前方、あるいは、後方に移動するために使用することができません。

WPFのナビゲーションFrameworkを使用する

Using the WPF Navigation Framework

Prismの領域ナビゲーションは、広範囲にわたる一般的なシナリオと難問に対処するように設計されていました。あなたは、疎く結合したナビゲーションを、モジュラーアプリケーションに実装するとき、直面するかもしれません。それは、MVVMパターンと依存関係注入コンテナを使用します。Unityや拡張管理フレームワーク(MEF)のような、また、それは、ナビゲーションの確認と取消し、既存のViewへのナビゲーション、ナビゲーション・パラメータとナビゲーション更新履歴をサポートするように設計されています。

Prism領域内でナビゲーションをサポートすることで、また、それは、広範囲にわたるレイアウト・コントロールのナビゲーションをサポートしています。そして、そのナビゲーション構造に影響を及ぼすことなく、アプリケーションUIの配置を変更するための機能をサポートしています。また、それは、ナビゲーションの間、高機能なユーザーとの対話処理ができる擬似同期ナビゲーションをサポートしています。

しかしながら、Prismの領域ナビゲーションは、WPFのナビゲーション・フレームワークを置き換えるように設計されていませんでした。その代わりに、Prism領域ナビゲーションは、WPFナビゲーション・フレームワークと並んで使用されるように、設計されていました。

MVVMパターンと依存関係の注入をサポートするためには、WPFナビゲーション・フレームワークは使いにくいです。また、それは、更新履歴とナビゲーションUIに関して、同じような機能を提供するFrameコントロールに基づいています。それは、Prism領域だけを使用して、ナビゲーションを実装することは、より簡単で、そして、より柔軟ですが、あなたは、Prism領域ナビゲーションと一緒にWPFナビゲーション・フレームワークを使用することができます。

領域ナビゲーション配列

The Region Navigation Sequence

次の図は、ナビゲーション操作の間の操作の配列の概要を説明します。それは、参照のために、提供されます。そのため、あなたが、Prism領域ナビゲーションのさまざまな要素が、ナビゲーションの要求の間、どのように、互いに動作するか確かめることができます。

ナビゲーション操作の間の操作の配列の概要

詳細情報

More Information

このエントリーをはてなブックマークに追加

Home PC C# Illustration

Copyright (C) 2011 Horio Kazuhiko(kukekko) All Rights Reserved.
kukekko@gmail.com
ご連絡の際は、お問い合わせページのURLの明記をお願いします。
「掲載内容は私自身の見解であり、所属する組織を代表するものではありません。」