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

8: Prism Library 5.0 for WPFを使用するナビゲーション

新規作成日 2016-06-08
最終更新日

8: Navigation Using the Prism Library 5.0 for WPF(原文)

Microsoft Prism Library 5.0 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では、このような状況で、ナビゲーションを実装するための案内を提供します。

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を参照します。

別の形式やスタイル内で、データを表示する

Displaying Data in Different Formats or Styles

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

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

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

Contact view navigation in the State-Based Navigation QuickStart

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

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

XAML


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

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

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

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

The Contact Details view in the State-Based Navigation QuickStart

あらためて、これは、Blend DataStateBehaviorを使用して、簡単に実装することができます。; しかしながら、ここでは、それは、ViewModel上のShowDetailsプロパティに結合されます。 ShowDetailsとShowContacts表示状態の間で、トグルスイッチの状態を示す、反転する移行アニメーションを使用しています。

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

Reflecting Application State

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

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

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

Connection state representation in the State-Based Navigation QuickStart

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

XAML


<ei:DataStateBehavior Binding="{Binding ConnectionStatus}" 
                                  Value="Available" 
                                  TrueState="Available" FalseState="Unavailable"/>

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

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

ユーザーと相互作用する

Interacting With the User

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

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

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

Interacting with the user using a pop-up window in the State-Based Navigation QuickStart

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

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

XAML


<prism:InteractionRequestTrigger SourceObject="{Binding SendMessageRequest}">
                <prism:PopupWindowAction IsModal="True">
                    <prism:PopupWindowAction.WindowContent>
                        <vs:SendMessagePopupView />
                    </prism:PopupWindowAction.WindowContent>
                </prism:PopupWindowAction>
            </prism:InteractionRequestTrigger>

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

View-Based Navigation

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

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

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

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

Prismの領域の概要

Prism Region Overview

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

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

XAML


<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オブジェクトに参照を取得するか、 あるいは、それにプログラム的にビューを追加するかを示します。 この例では、ビューは、依存関係注入コンテナを使用して作成されます。

C#


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

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

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

C#


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クラスによって実装されています。

C#


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

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

C#


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

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

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

C#


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

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

備考

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

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

C#


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

NavigationResultクラスは、ナビゲーション操作についての情報を提供する、プロパティを定義します。 Resultプロパティは、ナビゲーションが成功したかどうか示しています。 ナビゲーションが、機能しない場合、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つのメソッドを定義します。

C#


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インターフェイスを提供します。

C#


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インスタンスに、どのように、追加するかを示します。

C#


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メソッドのパラメータとして、渡します。これは、次のコードで、示されています。

C#


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メソッドを通して渡される、それぞれのパラメータに、 簡単なアクセスを可能にするインディクサー・プロパティを提供します。

C#


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

既存のビューに移動する

Navigating to Existing Views

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

最初のシナリオの例については、あなたのアプリケーションは、ユーザーが、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を返します。

C#


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オブジェクトを使用して、ナビゲーションを確認する

InteractionRequestオブジェクトを使用して、ナビゲーションを確認する

Confirming Navigation Using an InteractionRequest Object

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

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

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

C#


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; }
    }
}

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

XMAL


<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メソッドが、呼び出されます。 このメソッドの実装は、以前に定義した対話の要求を呼び出します。 それで、ユーザーが、ナビゲーション操作を確認、あるいは、キャンセルすることができます。

C#


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を渡すことができます。

C#


          NavigationContext navigationContext, Action<bool> continuationCallback)
{
    continuationCallback(true);
}

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

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

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

Using the Navigation Journal

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

C#


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インターフェイスを実装しています。 それは、次のように定義されています。

C#


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コマンドを実装することができます。

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

C#


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

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

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

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

領域ナビゲーション配列

The Region Navigation Sequence

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

Prism領域ナビゲーション配列

Prism領域ナビゲーション配列

Prism region navigation sequence

詳細情報

More Information

Prism領域の詳細については、ユーザー・インターフェイスを構成するを参照してください。

MVVMパターンと対話要求パターンの詳細については、MVVMパターンを実装する高等なMVVMの筋書きを参照してください。

対話要求オブジェクトの詳細については、高等なMVVMの筋書き内の、対話要求オブジェクト使用するを参照してください。

Visual State Managerの詳細については、MSDNのVisualStateManagerクラス(原文)を参照してください。

Microsoft Blendの動作を使用するの詳細については、MSDNの組み込みの動作とその動作(原文)を参照してください。

Microsoft Blendで、作成するカスタム・ビヘイビアの詳細については、MSDNの上でユーザー定義したビヘイビアを作成する(原文)を参照してください。

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

Home PC C# Illustration

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