原文:Composing the User Interface Using the Prism Library for WPF
複合アプリケーション・ユーザー・インターフェイス(UI)は、一般的に、アプリケーション・モジュールに含まれているViewとして知られている、疎く結合した視覚的なコンポーネントから、構成されていますが、それらは、行う必要はありません。あなたが、アプリケーションを、モジュールに分割する場合、あなたは、いくつかの方法で、UIをゆるく構成する必要があります。しかし、たとえ、Viewが、モジュールの中にないとしても、あなたは、このアプローチを使用する選択をするかもしれません。ユーザーのために、アプリケーションは、継ぎ目のないユーザー経験を提供し、そして、完全に統合されたアプリケーションを提供します。
あなたのUIを構成するために、あなたは、実行時に生成する、疎く結合した視覚的な要素で構成するレイアウトを作成できる構造が必要です。 さらに、アーキテクチャは、疎く結合したスタイルで情報をやりとりするために、これらの視覚的な要素のための戦略を提供する必要があります。
アプリケーションUIは、次に示すパラダイムの1つを使用することにより構築できます。:
- フォ-ムのために、すべての必要とされるコントロールは、設計時にフォ-ムを構成する、一つのExtensible Application Markup Language (XAML)ファイルに含まれています。
- フォ-ムの論理的な領域は、一般的に、ユーザー・コントロールのそれぞれの部品に分割されます。部品は、フォ-ムによって参照され、そして、フォ-ムは、設計時に、構成されます。
- フォ-ムの論理的な領域は、一般的に、ユーザー・コントロールのそれぞれの部品に分割されます。部品は、フォームの実行時に動的に追加されるフォ-ムに知られていません。アプリケーションは、UIの構成パターンを使用して、複合アプリケーションとして知られている、この方法論を使用します。
次の図に示すように、株トレーダーの参考になる実装(株トレーダーRI)は、シェルで公開される領域を経由して、異なるモジュールからもたらされる複数のビューを読み込むことによって構成されます。
UIのレイアウトの概念
UI Layout Concepts
複合アプリケーションのルート・オブジェクトは、シェルとして知られています。シェルは、アプリケーションのためのマスター・ページとして動作します。シェルは、1つ以上の領域が含まれています。領域は、実行時に、読み込まれる内容のためのフォルダーの場所です。領域は、ContentControl、ItemsControl、TabControlやカスタム・コントロールと管理されるUI要素の内容のような、UI要素に添付されます。領域の内容は、アプリケーションの必要条件によって、自動的に、あるいは、要求に応じて読み込むことができます。
一般的に、領域の内容は、Viewです。Viewは、あなたが、アプリケーションの他の部分から、可能な限り分離して維持したいかもしれない、あなたのUIの一部をカプセル化します。あなたは、ユーザー・コントロール、データ・テンプレートやカスタム・コントロールでさえ、Viewを定義することができます。
領域は、Viewのディスプレイとレイアウトを管理します。領域は、動的にViewを追加、あるいは、削除をサポートすることによって、それらの名前で分離された方法でアクセスすることができます。領域は、ホスティング・コントロールに接続されます。領域は、Viewが、動的に読み込まれる、コンテナとして考えてください。
次のセクションでは、複合アプリケーション開発のための高水準の中心的な概念を持ち出します。
シェル
Shell
シェルは、主要なUIの内容が含まれている、アプリケーション・ルート・オブジェクトです。Windows Presentation Foundation(WPF)アプリケーションでは、シェルは、Windowオブジェクトです。
シェルは、アプリケーションのためのlayout構造を提供する、マスター・ページの役割を果たしています。シェルには、モジュールが表示されるViewの場所を指定することができる1つ以上の名前を付けた領域が含まれています。また、それは、バックグラウンド、メインメニューとツールバーのような、特定の最上位のUI要素を定義することができます。
シェルは、アプリケーションの全体的な外観を定義します。それは、シェルのレイアウト自体に存在し、表示されているスタイルと境界線を定義している場合があります。そして、また、それは、シェルに接続されているViewに適用される、スタイル、テンプレートとテーマを定義しているかもしれません。
一般的に、シェルは、WPFアプリケーション・プロジェクトの一部です。シェルが含まれるアセンブリは、シェルの領域で読み込まれるViewが含まれている、アセンブリを参照するかもしれないし、参照しないかもしれません。
View
Viewは、複合アプリケーション内のUI構築のメインユニットです。あなたは、ユーザー・コントロール、ページ、データ・テンプレート、あるいは、カスタム・コントロールとして、Viewを定義することができます。Viewは、あなたが、アプリケーションの他の部分から、可能な限り分離して維持したいかもしれない、あなたのUIの一部をカプセル化します。あなたは、カプセル化や機能の一部に基づいて、ビューで何が起こるかを選択することができます。あるいは、あなたは、アプリケーション内で、そのViewの複数のインスタンスを持っているため、Viewとして、何を定義するか選択することができます。
WPFの内容モデルのため、Viewを定義するために要求されるPrismライブラリに固有のものは、何もありません。Viewを定義する最も簡単な方法は、ユーザー・コントロールを定義することです。ViewをUIに追加するために、あなたは、単純に、それを構築して、それをコンテナに追加する方法を必要とします。WPFは、これを行う仕組みを提供します。Prismライブラリは、Viewが、実行時に、動的に追加できる領域を定義するための機能を追加します。
複合View
Composite Views
特定の機能をサポートするViewは、複雑にすることができます。その場合、いくつかの子Viewに、Viewを分割するといいかもしれません。そして、部品としての子Viewを使用して、それ自体を構築している親Viewを操作する機能があります。アプリケーションは、設計時に、静的にこれを行う可能性があります。あるいは、それは、実行時に、モジュールが含まれている領域を通して、子Viewを追加することを、サポートするかもしれません。あなたが、単一のビュークラスで、完全に定義されていないViewを持っているとき、あなたは、複合Viewとして、それを参照することができます。多くの状況では、複合Viewは、子Viewを構築するための、そして、それらの間で相互作用を調整することのための役割を果たします。あなたは、Prismライブラリ・コマンドとイベント・アグリゲータを使用して、それらの同類のViewとそれらの親の複合Viewから、より疎く結合している子Viewを設計することができます。
Viewとデザイン・パターン
Views and Design Patterns
Prismライブラリは、あなたが使用する必要はありませんが、あなたは、いくつかのUIデザイン・パターンの1つを使うことを考える必要があります。Viewを実装するとき、株トレーダーRIとクイックスタートは、ViewのレイアウトとViewのロジックの間で、明確な分離を実装する方法として、Model-View-ViewModel(MVVM)パターンを説明します。
MVVM UIデザインパターンは、Microsoft XAMLプラットホームに自然に適合するため、推奨されます。依存関係プロパティ・システムとこれらのプラットホームの高機能なデータ結合の積み重ねは、疎く結合した方法で情報をやりとりするViewとView Modelに有効です。
ロジックをViewから分離することは、テスト容易性と保守性のために重要です。そして、それは、開発者-デザイナー間の仕事の流れを改善します。
あなたが、ユーザー・コントロールやカスタム・コントロール付きのViewを作成する場合、そして、分離コード・ファイルに、すべてのロジックを配置します。あなたは、ロジックの単体テストに、Viewのインスタンスを作成する必要があるため、あなたのViewは、検証することが困難です。これは、Viewが、その実行コンテクストの一部として、WPFコンポーネントから派生する、あるいは、依存する場合、特に問題です。あなたが、これらの依存関係なしで隔離した状態で、Viewロジックを単体テストできることを確認するために、あなたは、Viewとロジックのために、分離したクラスを必要とする実行コンテクストの依存関係を取り除くために、Viewのモックアップを作成できることが必要です。
あなたが、データ・テンプレートとしてViewを定義する場合、Viewそのものに、関連付けられたコードがありません。その結果、あなたは、他の場所で、関連するロジックを配置する必要があります。また、テスト容易性のためのレイアウトからロジックの同様の明確な分離は、保守するのがより簡単なViewを作成するのを支援するために必要です。
備考: 単体テストとUI自動化テストは、異なる適用範囲で検証するための2つの異なる形式です。
単体テストの推奨される最も効率のよい手法は、オブジェクトが、分離されて検証されます。オブジェクトの分離を達成するために、あなたは、それぞれの外部の依存関係のために、モックアップや下位モジュールの代用品が必要になります。続いて、粗い単体テストは、オブジェクトに対して実行されます。
UI自動化テストは、アプリケーションを実行し、UIにジェスチャーが適用され、そして、その次に、期待される結果のために検証が行われます。この種のテストは、UI要素が、アプリケーション・ロジックに正しく結合されていることを、確かめます。
ロジックをViewから分離することは、関係を明確に分離します。テスト容易性に関する注意事項に加えて、この分離は、UI上で、デザイナーが、開発者と独立して、働くことを可能にします。MVVMの詳細については、MVVMパターンを実装するを参照してください。
コマンド、UIのトリガ、動作とふるまい
Commands, UI Triggers, Actions, and Behaviors
Viewが、分離コード・ファイルで、そのロジックを実装するとき、あなたは、UIの相互作用を便利にするためにイベントハンドラを追加します。しかしながら、あなたが、MVVMを使用すると、View Modelは、UIで呼び出されるイベントを直接処理することができません。View Modelに、UIのジェスチャー・イベントを送るために、あなたは、コマンドやUIのトリガ、動作とふるまいを使用することができます。
コマンド
Commands
コマンドは、コマンドを実行するロジックから、コマンドを起動する意味規則とオブジェクトを分離します。動作が利用できるかどうかを示す機能が、コマンドに構築されます。UIのコマンドは、View ModelのICommandプロパティに結合されるデータです。コマンドの詳細については、コマンドのMVVMパターンを実装するを参照してください。
UIトリガ、動作とふるまい
UI Triggers, Actions, and Behaviors
トリガ、動作とふるまいは、Microsoft.Expression.Interactivity名前空間の一部で、Visual Studio 2013のためのBlendで運ばれます。また、それらはBlend SDKの一部です。UIのイベントやコマンドを取り扱うための、トリガ、動作とふるまいは、包括的なAPIを提供します。 そして、その次に、それらを、DataContextによって公開されるICommandプロパティ・メソッドに、送ります。UIのトリガ、動作、とふるまいの詳細については、「MVVMパターンを実装する」のセクションと「高等なMVVMの筋書き」の中の「トリガとコマンドの相互作用」を参照してください。
ユーザー相互作用
User Interactions
ユーザーとの対話処理は、アプリケーションがユーザーに贈る相互作用です。これらの相互作用は、一般的に、ユーザーに提示されるポップアップウィンドウです。MVVMの筋書きでは、これらのユーザーとの対話処理は、Viewから、あるいは、View Modelから作成することができます。Prismは、View Modelが、ユーザーとの対話処理を要求する必要があるとき、そして、指定されたイベントが、起動されたとき、Viewが、コマンドを呼び出す必要がある時のためのInvokeCommandAction動作は、InteractionRequestsと事例のために、InteractionRequestTriggersを提供します。
ユーザー相互作用、例とそれらを使用する方法の詳細については、インタラクティブ性のクイックスタートを参照してください。
データ結合
Data Binding
データ結合は、XAMLのプラットホームの最も重要なフレームワーク機能の1つです。XAMLのプラットホーム上で、うまくアプリケーションを開発するために、あなたは、データ結合をしっかりと理解する必要があります。
データ結合は、依存関係プロパティ・システムで、提供される固有の変更通知を最大限に活用します。INotifyPropertyChangedインターフェイスの共通言語ランタイム(CLR)のクラス実装と組み合わせると、変更通知は、データ結合に関与している対象とソース・オブジェクトの間に、コードなしで相互作用を有効にします。
データ結合は、1つの型を他の型に変換する値コンバータを使用して、異なる目標とソースの型をデータ結合に使用可能にします。データ結合は、あなたが、ユーザー入力を検証するために、使用することができる、そのパイプラインの中で、複数の妥当性検証フックを備えています。
あなたが、MSDNの依存関係プロパティの概要とデータ結合の概要の話題を読むことを強くお勧めします。これらの2つの話題を十分に理解することは、Microsoft XAMLプラットホーム上で、効率よくアプリケーションを開発するために、重要な意味があります。データ結合の詳細については、データ結合のMVVMパターンを実装するを参照してください。
Region
Regions
領域は、領域マネージャ、領域と領域アダプタによって、Prismライブラリで使用できます。次の項目では、それらが、互いにどのように動作するかについて説明します。
領域マネージャー
Region Manager
RegionManagerクラスは、ホスト・コントロールのために、領域のコレクションを作成し、管理するための役割を果たします。RegionManagerは、新しい領域とホスト・コントロールを関連付けるコントロール固有のアダプタを使用します。次の図は、RegionManagerによって、領域、コントロールとアダプタの間で設定される、リレーションシップを示します。
RegionManagerは、コードやXAML内で、領域を作成することができます。RegionManager.RegionName添付プロパティは、添付プロパティをホスト・コントロールに適用することによって、XAMLで領域を作成するために使用されます。
Applicationsは、RegionManagerの1つ以上のインスタンスを含むことができます。あなたは、あなたが、領域を登録したい、RegionManagerインスタンスを指定することができます。あなたが、コントロールをビジュアル・ツリーに移動したい場合、これは役に立ちます。そして、添付プロパティの値が削除されたとき、領域をクリアする必要はありません。
RegionManagerは、その領域を共有されたデータにする、RegionContext添付プロパティを提供します。
領域の実装
Region Implementation
領域は、IRegionインターフェイスを実装するクラスです。領域という用語は、UIに示される動的なデータを格納することができるコンテナを表します。領域は、Prismライブラリを、UIのコンテナ内の、定義済みプレースホルダのモジュールに含まれる動的なコンテンツに配置できます。
領域は、どんなUIコンテンツの型も格納することができます。モジュールは、ユーザー・コントロール、データ・テンプレート、カスタム・コントロール、あるいは、これらのどんな組合せにでも関連付けられるデータ型として示される、UIコンテンツを含めることができます。これは、あなたが、UI領域のための外観を定義できます。そして、その次に、これらの予め定められた領域のコンテンツに配置したモジュールを持っています。
領域は、0以上項目を含めることができます。領域が管理しているホスト・コントロールの型に従い、一つ以上の項目は、表示されることがありえました。例えば、ContentControlは、一つのオブジェクトだけを表示することができます。しかしながら、それが配置される領域は、多くの項目を含めることができます。そして、UIで表示される領域で、それぞれの項目を提供するItemsControlは、複数の項目を表示することができます。
次の説明の、株トレーダーRIシェルには、4つの領域が含まれています。:MainRegion、MainToolbarRegion、ResearchRegionとActionRegion。これらの領域は、アプリケーションにおいてさまざまなモジュールに埋め込まれます。-内容は、いつでも変更することができます。
マッピングしている領域へのモジュール・ユーザー・コントロール
Module User Control to Region Mapping
どのようなモジュールと内容が、領域で関連付けられるか説明するために、次の図を見て下さい。それは、シェルの対応する領域に、WatchModuleとNewsModuleの関連付けを示します。
MainRegionには、WatchModuleに含まれてる、WatchListViewのユーザー・コントロールが含まれています。ResearchRegionは、同様に、NewsModuleに含まれている、ArticleViewユーザー・コントロールが含まれています。
Prismライブラリで作成されたアプリケーションでは、このようなマッピングは、設計者と開発者は、それらを、どんな内容が、特定の領域に提案されているかを決定するために使用するため、設計プロセスの一部です。これは、デザイナーが、必要な全体的な空間とどんな追加された内容が、許容される空間で見えるように、確認するために追加する必要がある項目でも決定できます。
既定領域の機能
Default Region Functionality
あなたが、それらを使用するための領域の実装を完全に理解する必要がない間、それは、コントロールと領域がどのように関連付けられ、そして、既定の領域の機能を理解するために役に立つかもしれません。:例えば、どのように、領域を配置し、そして、Viewをインスタンスかするか、 それらが、アクティブViewであるとき、Viewが、どのように通知されか、あるいは、Viewの寿命が、アクティブ化に、どのように結び付けられるか、
次のセクションでは、領域アダプタと領域のふるまいを説明します。
領域アダプタ
Region Adapter
領域としてUIコントロールを公開するために、領域アダプタを持っている必要があります。領域アダプタは、領域を作成するための、そして、それとコントロールを関連付けるための、役割を果たします。これは、あなたが、同一の方法で、UIコントロールの内容を管理するために、IRegionインターフェイスを使用できます。それぞれの領域アダプタは、UIコントロールの特定の型に合わせます。Prismライブラリは、次の3つの領域アダプタを提供します。:
- ContentControlRegionAdapter。 このアダプタは、System.Windows.Controls.ContentControl型と派生クラスのコントロールに適応させます。
- SelectorRegionAdapter。 このアダプタは、System.Windows.Controls.TabControlコントロールのような、System.Windows.Controls.Primitives.Selectorクラスから派生したコントロールに適応させます。
- ItemsControlRegionAdapter。 このアダプタは、System.Windows.Controls.ItemsControl型と派生クラスのコントロールに適応させます。
領域ビヘイビア
Region Behaviors
Prismライブラリは、領域ビヘイビアの概念を導入します。これらは、領域に大部分のその機能を与える、接続可能なコンポーネントです。(このトピックで後述される)領域ビヘイビアは、View発見と地域背景をサポートするために導入されました。そして、APIを作成するために、 WPFとSilverlightの両方で、一貫性があります。さらに、ふるまいは、領域の実装を拡張するための効果的な方法を提供します。
領域ビヘイビアは、領域に追加された機能を与えるために領域に添付されるクラスです。このふるまいは、領域に添付され、領域の寿命のためにアクティブなままです。例えば、AutoPopulateRegionBehaviorが、領域に添付されるとき、それは、自動的に、インスタンスを生成し、そして、その名前の領域に対して登録される、どんなViewTypesでも追加します。領域の寿命のために、それは、新しい登録のために、RegionViewRegistryを監視し続けます。それは、システム全体、あるいは、地域単位基準のどちらでも、ユーザー定義した領域ビヘイビアを追加することが、あるいは、既存のふるまいを置き換えることが簡単です。
次の項目では、自動的に、すべての領域に追加する、既定の動作を説明します。1つのふるまいとして、SelectorItemsSourceSyncBehaviorは、Selectorから派生するコントロールに添付されるだけです。
ビヘイビアの登録
Registration Behavior
RegionManagerRegistrationBehaviorは、領域が正しいRegionManagerに登録されていることを確認するための役割を果たします。Viewやコントロールが、他のコントロールの子、あるいは、領域のとして、ビジュアル・ツリーに追加されるとき、コントロールに定義されたどんな領域でも、親のコントロールのRegionManagerで登録する必要があります。子のコントロールが削除されるとき、登録された領域は、登録されていません。
自動的な母集団のふるまい
Auto-Population Behavior
View発見を実装するために、役割を果たす2つのクラスがあります。それらの一つは、AutoPopulateRegionBehaviorです。それが、領域に添付されるとき、領域という名前で登録される、すべてのView型を取得します。それは、続いて、それらのViewのインスタンスを作成し、そして、それらを領域に追加します。領域が作成されたあと、AutoPopulateRegionBehaviorは、その領域の名前のための、どんな新たに登録されたView型でも、RegionViewRegistryを監視します。
あなたが、View発見プロセスをより多く制御したい場合、IRegionViewRegistryとAutoPopulateRegionBehaviorのあなた独自の実装を作成することを考えてみてください。
コンテクスト・ビヘイビア領域
Region Context Behaviors
領域コンテクストの機能は、2つのふるまいの中に含まれています。:SyncRegionContextWithHostBehaviorとBindRegionContextToDependencyObjectBehavior。これらのふるまいは、領域で作成されたコンテクストに変更を監視するための役割を与えます。そして、その次に、コンテクストとViewに添付されるコンテクスト依存関係プロパティを同期させます。
ビヘイビアのアクティブ化
Activation Behavior
RegionActiveAwareBehaviorは、アクティブ、あるいは、非アクティブである場合、Viewに通知するための役割を果たします。Viewは、これらの変更通知を受け取るIActiveAwareを実装している必要があります。このアクティブな通知の認識は(ビヘイビアからViewに移動する)一方向性です。Viewは、IActiveAwareインターフェイスでアクティブ・プロパティを変更することによって、そのアクティブな状態に影響を及ぼすことができません。
ビヘイビア領域の寿命
Region Lifetime Behavior
RegionMemberLifetimeBehaviorは、非アクティブになるとき、項目が、領域から削除される場合、決定するための役割を果たします。 RegionMemberLifetimeBehaviorは、項目を発見するために、非アクティブ状態に移行する領域のActiveViewsコレクションを監視します。 ビヘイビアは、削除された上で、生きた状態で維持する必要がある場合、(その順番で)決定するための、IRegionMemberLifetime、あるいは、RegionMemberLifetimeAttributeのための削除された項目を確認します。
コレクションの項目が、System.Windows.FrameworkElementである場合、また、それは、IRegionMemberLifetimeやRegionMemberLifetimeAttributeのためのそのDataContextを確認します。
領域の項目は、以下の順序で確認されます:
- IRegionMemberLifetime.KeepAlive値
- DataContextのIRegionMemberLifetime.KeepAlive値
- RegionMemberLifetimeAttribute.KeepAlive値
- DataContextのRegionMemberLifetimeAttribute.KeepAlive値
コントロール固有のビヘイビア
Control-Specific Behaviors
SelectorItemsSourceSyncBehaviorは、WPFのTabコントロールのような、Selectorから派生するコントロールのために、一つたけ使用されています。それは、セレクタの項目で領域で、そして、その次に、領域内の同期するアクティブViewのセレクタの選択した項目で、Viewを同期させるための役割を果たします。
領域の実装を拡張する
Extending the Region Implementation
Prismライブラリは、カスタマイズ可能な拡張ポイントを提供します。あるいは、提供されたAPIの既定の動作を拡張します。例えば、あなたは、ナビゲーションAPIが、URIsを解析する、あなた独自の領域アダプタ、領域ビヘイビアや変更方法を記述することができます。Prismライブラリを拡張する方法の詳細については、Prismライブラリを拡張するを参照してください。
Viewの構成
View Composition
View構成は、Viewから構築されています。複合物アプリケーションでは、複数のモジュールからのViewは、アプリケーションUI内の特定の場所で、実行時に表示される必要があります。これを達成するために、あなたは、Viewが表示される場所、そして、Viewが、どのように作成され、表示される、それらの場所を定義する必要があります。
Viewは、自動的に、View発見を通して、あるいは、プログラム上でview注入を通してどちらかの場所で、作成、そして、表示することができます。これらの2つの技術は、それぞれのViewが、アプリケーションUI内の場所に名前を付けるために、どのように、マッピングするか決定します。
View発見
View Discovery
View発見では、あなたは、RegionViewRegistryで、領域の名前とViewの型の間の、リレーションシップを設定します。領域が作成されるとき、領域は、領域と自動的にインスタンスを生成、そして、対応するViewを読み込みに関連する、すべてのViewTypesを探します。その結果、 View発見を使用して、あなたは、領域に一致するViewが、読み込まれ、表示される時、制御をこえて、明示する方法を持っていません。
View注入
View Injection
View注入では、あなたのコードは、領域に参照を取得し、そして、その次に、Viewが、プログラム的に追加されます。通常、これは、モジュールを初期化する時、あるいは、ユーザーの動作の結果として、実行されます。あなたのコードは、RegionManagerに名前で特定の領域を問い合わせ、そして、その次に、Viewを注入します。View注入で、あなたは、Viewが、読み込まれ、表示されるとき、より多くの制御を持っています。また、あなたは、領域から、Viewを削除するための機能を持っています。しかしながら、あなたは、View注入で、まだ作成されていない領域に、Viewを追加することができません。
ナビゲーション
Navigation
Prismライブラリ4.0には、ナビゲーションAPIが含まれています。ナビゲーションAPIは、あなたが、領域をURIに操作できるview注入プロセスを簡素化します。ナビゲーションAPIは、Viewのインスタンスを生成し、領域に、それを追加し、そして、その次に、それをアクティブ化します。さらに、ナビゲーションAPIは、領域に含まれる、以前に作成されたViewへ戻る操作ができます。ナビゲーションAPIの詳細については、ナビゲーションを参照してください。
View発見とView注入を使用する場合
When to Use View Discovery vs. View Injection
領域は、依存するアプリケーション要件と領域の機能を使用するために、Viewの読み込み戦略を選択します。
次に示す状況で、View発見を使用します。:
- 自動View読み込みは、要求される、あるいは、必要とされます。
- Viewの一つのインスタンスは、領域に読み込まれます。
次に示す状況で、View注入を使用します。:
- あなたのアプリケーションは、ナビゲーションAPIを使用します。
- Viewが作成され、表示される、あるいは、領域からViewを削除する必要があるとき、あなたは、明示する、あるいは、プログラムに基づいて、制御する必要があります。;例えば、アプリケーションのロジックやナビゲーションの結果として、
- あなたは、それぞれのViewインスタンスが、異なるデータに結合される領域で、同じViewの複数のインスタンスを表示する必要があります。
- あなたは、Viewが追加される領域のインスタンスを制御するために必要です。例えば、あなたは、特定の利用者の内容の領域に、顧客の内容のViewを追加することを望みます。(この筋書きは、この話題の後で説明される、実装するスコープの領域を必要とします)。
UIレイアウトの筋書き
UI Layout Scenarios
複合物アプリケーションでは、複数のモジュールからのViewは、アプリケーションUI内の特定の場所の中で、実行時に表示されます。これを達成するために、あなたは、Viewが表示される場所、そして、Viewが、どのように作成され、表示される、それらの場所を定義する必要があります。
それは、Viewの分離し、そして、UI内の場所に外観、そして、領域の中で表示される、Viewと独立して進化するアプリケーションのレイアウトを表示するでしょう。
次の項目では、あなたが、複合アプリケーションを開発するとき、あなたが遭遇する中心的な筋書きを説明します。適切な場合、株トレーダーRIの例は、筋書きのための解決策を説明するために使用されます。
シェルを実装する
Implementing the Shell
シェルは、主要なUIコンテンツが含まれているアプリケーションのルート・オブジェクトです。Windows Presentation Foundation(WPF)アプリケーションでは、シェルは、Windowオブジェクトです。
シェルは、モジュールが表示されるViewを指定できる名前を付けた領域を含めることができます。また、それは、メインメニューとツールバーのような、特定の最上位のUI要素を定義することができます。シェルは、アプリケーションのための全体的な構造と外観を定義し、そして、ASP.NETのマスター・ページ・コントロールと類似しています。それは、シェルのレイアウトそのものに存在し表示される、スタイルと境界線を定義することができます。そして、また、それは、シェルに接続され、Viewに適用されるスタイル、テンプレートとテーマを定義できます。
あなたは、Prismライブラリを使用するために、アプリケーション・アーキテクチャの一部として、異なったシェルを持つ必要はありません。あなたが、完全に新しい複合アプリケーションを構築している場合、シェルを実装することは、明確に定義されたルート、そして、あなたのアプリケーションの中心となるUIを設定するための初期化パターンを提供します。しかしながら、あなたが、Prismライブラリの機能を既存のアプリケーションに追加している場合、あなたは、シェルを追加するアプリケーションの基本的なアーキテクチャを変更する必要はありません。その代わりに、あなたは、必要に応じてViewを引き出すことができる領域を追加するために、既存のウィンドウ定義やコントロールを変更することができます。
また、あなたにはアプリケーションに、1つ以上のシェルを持つことができます。あなたのアプリケーションが、ユーザーのために、1つ以上の最上位ウィンドウを開くための設計がされている場合、それぞれの最上位ウィンドウは、それが含まれる内容のシェルとして動作します。
株トレーダーRIのシェル
Stock Trader RI Shell
WPFの株トレーダーRIには、そのメイン・ウィンドウとしてシェルを持っています。次の説明では、シェルとViewに焦点を当てます。シェルは、株トレーダーRIが開始するとき、表示されるメイン・ウィンドウです。そして、それには、すべてのViewが含まれています。それは、領域を、CFIの株トレーダー・タイトルと監視リストの切り取りバナーが含まれている、Viewと最上位のUIの項目の一組を追加するモジュールに定義します。
株トレーダーRIのシェルの実装は、Shell.xaml、その分離コード・ファイルのShell.xaml.cs、そして、そのView ModelのShellViewModel.csによって提供されています。Shell.xamlには、モジュールが、Viewを追加する領域の定義が含まれているシェルの一部であるレイアウトとUI要素が含まれています。
次のXAMLは、シェルを定義する構造と中心となるXAMLの要素を示しています。RegionNameが、プロパティを添付した4つの領域を定義するために、ウィンドウの背景画像は、シェルのための背景を提供するために使用されることに注意します。
<!--Shell.xaml (WPF) -->
<Window x:Class="StockTraderRI.Shell">
<!--shell background -->
<Window.Background>
<ImageBrush ImageSource="Resources/background.png" Stretch="UniformToFill"/>
</Window.Background>
<Grid>
<!-- logo -->
<Canvas x:Name="Logo" ...>
<TextBlock Text="CFI" ... />
<TextBlock Text="STOCKTRADER" .../>
</Canvas>
<!-- main bar -->
<ItemsControl
x:Name="MainToolbar"
prism:RegionManager.RegionName="{x:Static inf:RegionNames.MainToolBarRegion}"/>
<!-- content -->
<Grid>
<Controls:AnimatedTabControl
x:Name="PositionBuySellTab"
prism:RegionManager.RegionName="{x:Static inf:RegionNames.MainRegion}"/>
</Grid>
<!-- details -->
<Grid>
<ContentControl
x:Name="ActionContent"
prism:RegionManager.RegionName="{x:Static inf:RegionNames.ActionRegion}"/>
</Grid>
<!-- sidebar -->
<Grid x:Name="SideGrid">
<Controls:ResearchControl
prism:RegionManager.RegionName="{x:Static inf:RegionNames.ResearchRegion}" />
</Grid>
</Grid>
</Window>
シェル・コード・ビハインド・ファイルの実装は、極めて簡単です。Shellがエクスポートされるため、ブートストラッパーが、それを作成する時、その依存関係は、拡張管理フレームワーク(MEF)で解決されます。次の例に示すように、シェルは、構築の間に注入されるShellViewModelの一つの依存関係を備えています。
// Shell.xaml.cs
[Export]
public partial class Shell : Window
{
public Shell()
{
InitializeComponent();
}
[Import]
ShellViewModel ViewModel
{
set
{
this.DataContext = value;
}
}
}
// ShellViewModel.cs
[Export]
public class ShellViewModel : BindableBase
{
// This is where any view model logic for the shell would go.
// ここは、シェルが進むためのView Modelロジックの場所です。
}
コード・ビハインド・ファイルの最小のコードは、複合アプリケーション・アーキテクチャの機能と単純さ、そして、シェルとその構成Viewの間の疎結合を説明します。
領域の定義
Defining Regions
あなたは、領域として知られている、Viewが定義したlocationsと名前を付けたレイアウトで表示される場所を定義します 。領域は、実行時に表示される1つ以上のViewのための記入子として動作します。モジュールは、どのように、そして、どこの領域に表示されるか知ることなく、内容をレイアウトに配置し、そして、追加することができます。これは、内容をレイアウトに追加するモジュールに影響を及ぼすことなく、レイアウトを変更できます。
領域は、XAML内で、先程のShell.xamlファイルやコードとして示された、WPFコントロールに領域の名前を割り当てることによって定義します。領域は、それらの領域の名前でアクセスすることができます。実行時に、Viewは、続いて、レイアウト戦略通りに、Viewが実装するViewやViewsを表示する、名前を付けたRegionコントロールに追加されます。例えば、Tabコントロールの領域は、タブ付きの配列で、その子Viewを配置します。領域は、Viewの追加や削除をサポートしています。Viewは、プログラム上で、あるいは、自動的に、領域内で作成し、そして、表示することができます。Prismライブラリでは、前者は、view注入を通して、後者は、View発見を通して達成されます。これらの2つの技術は、どのように、それぞれのViewが、アプリケーションUIの範囲内で名前を付けた領域にマッピングするかを決定します。
アプリケーションのシェルは、最高水準のアプリケーション・レイアウトを定義します。;例えば、次の図に示すように、中心となる内容とナビゲーションの内容のための場所を指定することによって、これらの高水準View内のレイアウトは、同じように定義し、全体のUIを再帰的に構成できます。
領域は、ときどき、論理的に関連がある複数のビューのための場所を定義するために使用されます。この予想される展開では、領域コントロールは、一般的に、それが実装するレイアウト戦略に従って、積み重ねられたり、タブ付きのレイアウト配置のような、Viewを表示するItemsControlから派生したコントロールです。
また、領域は、単一のViewのための場所を定義するために使用することができます。;例えば、ContentControlを使用して。この予想される展開では、領域コントロールは、たとえ1つ以上のViewが、その領域の場所にマッピングされているとしても、一度に、1つのViewだけを表示します。
株トレーダーRIのシェル領域
Stock Trader RI Shell Regions
また、アプリケーションが、株を売り買いするとき、複数のビュー・レイアウトが、株トレーダーRIで表示されています。Buy/Sell領域は、次の図に示すように、そのリストの一部として、複数のbuy/sell View(OrderCompositeView)を表示する、リスト・スタイルの領域です。
シェルのActionRegionには、OrdersViewが含まれています。OrdersViewは、OrdersRegionと同様にSubmit AllとCancel Allボタンが含まれています。OrdersRegionは、複数のOrderCompositeViewsを表示する、ListBoxコントロールに添付されます。
IRegion
IRegion
領域は、IRegionインターフェイスを実装するクラスです。領域は、コントロールによって表示される内容を格納する、コンテナです。次に示すコードは、IRegionインターフェイスを示しています。
public interface IRegion : INavigateAsync, INotifyPropertyChanged
{
IViewsCollection Views { get; }
IViewsCollection ActiveViews { get; }
object Context { get; set; }
string Name { get; set; }
Comparison<object> SortComparison { get; set; }
IRegionManager Add(object view);
IRegionManager Add(object view, string viewName);
IRegionManager Add(object view, string viewName, bool createRegionManagerScope);
void Remove(object view);
void Deactivate(object view);
object GetView(string viewName);
IRegionManager RegionManager { get; set; }
IRegionBehaviorCollection Behaviors { get; }
IRegionNavigationService NavigationService { get; set; }
}
XAMLで領域を追加する
Adding a Region in XAML
RegionManagerは、あなたは、XAML内で、簡単な領域の作成を使用することができる、添付プロパティを指定します。添付プロパティを使用するために、あなたは、XAMLに、Prismライブラリ名前空間を読み込み、そして、その次に、RegionName添付プロパティを使用する必要があります。次の例は、AnimatedTabControlと一緒に、ウィンドウの添付プロパティを、どのように、使用するかを表示します。
MainRegion文字列定数を参照するために、x:Staticマークアップ拡張機能を使用することに注意してください。この練習は、XAMLで魔法の文字列を除去します。
<!-- (WPF) -->
<Controls:AnimatedTabControl
x:Name="PositionBuySellTab"
prism:RegionManager.RegionName="{x:Static inf:RegionNames.MainRegion}"/>
コードを使用して、領域を追加します。
Adding a Region by Using Code
RegionManagerは、XAMLを使用することなく、領域ディレクトリを登録することができます。次のコードの例は、コード・ビハインド・ファイルからコントロールに領域を、どのように追加するかを示します。まず、領域マネージャへの参照を取得します。続いて、RegionManager静的メソッドのSetRegionManagerとSetRegionNameを使用して、領域は、UIのActionContentコントロールに、その次に、その領域は、ActionRegionという名前に添付されます。
IRegionManager regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
RegionManager.SetRegionManager(this.ActionContent, regionManager);
RegionManager.SetRegionName(this.ActionContent, "ActionRegion");
領域を読み込むとき、領域でViewを表示する
Displaying Views in a Region When the Region Loads
View発見の方法で、モジュールは、特定の名前を付けた場所のために、View(Viewモデルやプレゼンテーション・モデル)を登録することができます。その場所が、実行時に表示されるとき、どんなViewでも、その場所が、自動的に、作成され、表示されるために、登録されています。
モジュールは、レジストリでViewを登録します。親のViewは、名前を付けた場所のための登録されたViewを発見するために、このレジストリを問い合わせます。それらが発見されたあと、親のViewは、それらを記入子コントロールに追加することによって、画面上のそれらのViewに配置します。
アプリケーションが読み込まれたあと、複合Viewは、レジストリに追加された新しいViewの設置を取り扱うために、通知されます。
次に示す図は、View発見アプローチを示しています。
Prismライブラリは、これらの名前を付けた場所のためのViewを登録するために、標準的なレジストリのRegionViewRegistryを定義します。
領域内に、Viewを表示するには、次のコードの例に示すように、領域マネージャーとViewを登録します。あなたは、直接、領域でView型を登録することができます。この場合、領域を格納しているコントロールが読み込まれるとき、Viewは、依存関係注入コンテナで構築され、そして、領域に追加されます。
// View discovery
this.regionManager.RegisterViewWithRegion("MainRegion", typeof(EmployeeView));
必要に応じて、あなたは、次の例で示すように、表示されているViewを返すデリゲートを提供することができます。領域マネージャーは、領域が作成されるとき、Viewを表示します。
// View discovery
this.regionManager.RegisterViewWithRegion("MainRegion", () => this.container.Resolve<EmployeeView>());
UIの構成クイックスタートは、RegisterViewWithRegionメソッドを、どのように使用するかを説明する、EmployeeModule ModuleInit.csファイルのチュートリアルを持っています。
プログラムで、領域内にViewを表示する
Displaying Views in a Region Programmatically
View注入の方法で、Viewは、プログラムで、それらを管理するモジュールで、名前を付けた場所から、追加、あるいは、削除されます。これを使用可能にするために、アプリケーションには、UIの名前を付けた場所のレジストリが含まれています。モジュールは、場所の1つを検索するために、レジストリを使用することができ、そして、その次に、プログラム上で、それにViewを注入します。同様に、レジストリ内の場所にアクセスできることを確認するために、名前を付けた場所の各々は、viewを注入するために使用する、一般的なインターフェイスにくっつきます。次に示す図は、View注入アプローチを示しています。
Prismライブラリは、これらの場所にアクセスするため、標準的なレジストリ、RegionManagerと標準インタフェース、IRegionを定義します。
次のコードで示すように、領域にViewを追加するView注入を使用するために、領域マネージャーから領域を取得し、そして、その次に、Addメソッドを呼び出します。View注入で、Viewは、モジュールが読み込まれるとき、あるいは、ユーザーの動作が、定義済み動作を達成する時、発生することができるViewが領域に追加された後で、表示だけされます。
// View injection
IRegion region = regionManager.Regions["MainRegion"];
var ordersView = container.Resolve<OrdersView>();
region.Add(ordersView, "OrdersView");
region.Activate(ordersView);
株トレーダーRIに加えて、UIの構成クイックスタートは、View注入を実装することのための、チュートリアルを持っています。
領域ナビゲーション
Region Navigation
Prismライブラリ5.0には、WPFアプリケーションでナビゲーションを実装するための、豊富で、そして、一貫したAPIが提供される、ナビゲーションAPIが含まれています。
領域ナビゲーションは、View注入のフォ-ムです。ナビゲーションの要求が処理されるとき、それは、要求を満たすことができる領域内に、Viewを配置しようとします。それが、一致するViewを見つけることができない場合、それは、オブジェクトを作成するアプリケーション・コンテナを呼び出し、その次に、対象とする領域にオブジェクトを注入して、それを起動させます。
株トレーダーRI ArticleViewModelからの次のコードの例は、ナビゲーションの要求を、どのように開始するかを説明します。
this.regionManager.RequestNavigate(RegionNames.SecondaryRegion, new Uri("/NewsReaderView", UriKind.Relative));
領域ナビゲーションの詳細については、ナビゲーションを参照してください。また、ビュー切り替えナビゲーション・クイックスタートと状態に基づいたナビゲーション・クイックスタートは、アプリケーション・ナビゲーションを実装する例です。
領域内の並べ替えView
Ordering Views in a Region
それが、View発見やView注入を使用するかどうかに関係なく、アプリケーションは、複数のアクティブなViewを表示する、TabControl、ItemsControlや他のどのコントロールでも、どのようにViewを表示されるかを並べる必要があるかもしれません。既定では、Viewは、それらが領域に登録され、追加された順序で表示します。
複合アプリケーションが構築されるとき、Viewは、多くの場合、異なるモジュールから登録されます。モジュール間で依存関係を宣言することは、問題の軽減を助けることができますが、モジュールとViewが、本当に相互依存を少しももっていない時、必要以上に不自然な依存関係を一対のモジュールに宣言します。
Viewが、自分自身を並べることに、関与できるようにするために、Prismライブラリは、ViewSortHint属性を提供します。この属性には、Viewが、領域内で、どのように、それが、並べかえる必要があるかのヒントを宣言できる、文字列のヒント・プロパティが含まれています。
Viewを表示するとき、Regionクラスは、Viewを並べるためにヒントを使用する、既定のView整列ルーチンを使用します。これは、簡単な、大文字と小文字の区別ができる順序の並べ替えです。並べ替えのヒント属性を持っているViewが、ないものを先に並べます。また、属性のないものは、領域に追加された順で表示されます。
あなたが、Viewがどのように並べるかの変更したい場合、Regionクラスは、あなたが、あなた独自のComparison<object>デリゲート・メソッドで設定することができる、SortComparisonプロパティを提供します。ItemsControlRegionAdapterのようなアダプタが、直接、これらのプロパティに結合するため、領域のViewとActiveViewsプロパティの順位付けが、UIに反映されることに注意することが重要です。ユーザー定義した領域アダプタは、どのように、領域がViewを並べ替えるかを上書きする、それ自身の並べ替えとフィルターを実装することができます。
ビューの切り替えのクイックスタートは、左辺のナビゲーション領域でViewを並べるための、簡単な番号付け方式を説明します。次のコードの例は、ナビゲーション項目Viewの各々に適用されるViewSortHintを表示します。
[Export]
[ViewSortHint("01")]
public partial class EmailNavigationItemView { ... }
[Export]
[ViewSortHint("02")]
public partial class CalendarNavigationItemView { ... }
[Export]
[ViewSortHint("03")]
public partial class ContactsDetailNavigationItemView { ... }
[Export]
[ViewSortHint("04")]
public partial class ContactsAvatarNavigationItemView { ... }
複数の領域の間のデータの共有
Sharing Data Between Multiple Regions
Prismライブラリは、あなたの筋書きに依存する、Viewの間で情報をやりとりする、複数の方法を提供します。領域マネージャーは、これらの方法の1つとして、RegionContextプロパティを提供します。
あなたが、領域に格納される親Viewと子Viewの間でコンテクストを共有したいとき、RegionContextは、役に立ちます。RegionContextは、添付プロパティです。あなたは、領域コントロール上の、コンテクストの値を設定するため、それは、領域コントロールで表示する、すべての子Viewを利用できるようにすることができます。領域コンテクストは、どんな簡単な、あるいは、複雑なオブジェクトでも、そして、データバインド値でもできます。RegionContextは、View発見やView注入のどちらでも使用することができます。
備考 WPFのDataContextプロパティは、Viewのためのローカルデータ・コンテクストを設定するために、使用されます。それは、Viewが、View Model、ローカル・プレゼンターやモデルで情報をやりとりするための、データ結合を使用できます。RegionContextは、複数のビューの間で、そして、単一のViewへのローカルではない、コンテクストを共有するために使用されています。それは、複数のビューの間で、コンテクストを共有するための、簡単な仕組みを提供します。
次のコードは、XAMLのRegionContext添付プロパティが、どのように使用されるかを表示します。
<TabControl AutomationProperties.AutomationId="DetailsTabControl"
prism:RegionManager.RegionName="{x:Static local:RegionNames.TabRegion}"
prism:RegionManager.RegionContext="{Binding Path=SelectedEmployee.EmployeeId}"
...>
次の例に示すように、あなたは、また、コードのRegionContextを設定することができます。
RegionManager.Regions["Region1"].Context = employeeId;
ViewのRegionContextを取得するには、RegionContextクラスのGetObservableContext staticメソッドは、使用されます。次のコードの例に示すように、それは、パラメータとしてViewを渡して、続いて、そのValueプロパティにアクセスします。
private void GetRegionContext()
{
this.Model.EmployeeId = (int)RegionContext.GetObservableContext(this).Value;
}
RegionContextの値は、単純に、新しい値を、そのValueプロパティに割り当てることによって、View内から変更されることができます。Viewは、GetObservableContextメソッドによって返される、ObservableObject上でPropertyChangedイベントを購読することによって、RegionContextに変更を通知することを選択することができます。それは、それらのRegionContextが変更されるとき、複数のビューを同期し続けることができます。次のコードの例は、PropertyChangedイベントを購読することを説明します。
ObservableObject<object> viewRegionContext =
RegionContext.GetObservableContext(this);
viewRegionContext.PropertyChanged += this.ViewRegionContext_OnPropertyChangedEvent;
private void ViewRegionContext_OnPropertyChangedEvent(object sender,
PropertyChangedEventArgs args)
{
if (args.PropertyName == "Value")
{
var context = (ObservableObject<object>) sender;
int newValue = (int)context.Value;
}
}
備考: RegionContextは、内容のオブジェクトの添付プロパティが領域で格納したので、設定されます。これは、内容のオブジェクトがDependencyObjectから、派生することを示しています。前述の例では、Viewは、最終的に、DependencyObjectから派生する、ビジュアル・コントールです。
あなたが、あなたのViewを定義するWPFのデータ・テンプレートを使うことを選択する場合、内容オブジェクトは、ViewModelやPresentationModelを表します。あなたのViewモデルやプレゼンテーション・モデルが、RegionContextを取り出すことを必要とする場合、それは、DependencyObject基底クラスから派生する必要があります。
領域の複数のインスタンスを作成する
Creating Multiple Instances of a Region
スコープの領域は、View注入でのみ利用できます。あなたは、あなたが、領域のそれ自身のインスタンスを持つために、Viewが必要な場合、それらを使用する必要があります。自動的に添付プロパティで領域を定義するViewは、それらの親のRegionManagerを継承します。通常、これは、シェルウィンドウの中で登録される、グローバルRegionManagerです。アプリケーションが、そのViewの1つ以上のインスタンスを作成する場合、それぞれのインスタンスは、親のRegionManagerでその領域を登録しようとします。RegionManagerは、一意の名前を付けた領域だけを提供します。;したがって、2回目の登録は、エラーを生じます。
その代わりに、次の図に示すように、スコープされた領域を使用するため、各々のViewは、それ自身のRegionManagerを持っており、そして、その領域は、親のRegionManagerではなく、そのRegionManagerで登録されます。
次のコードの例で説明されるように、あなたが、あなたのViewを領域に追加するとき、Viewのための、ローカルRegionManagerを作成するために、作成する必要がある、新しいRegionManagerを指定します。
IRegion detailsRegion = this.regionManager.Regions["DetailsRegion"];
View view = new View();
bool createRegionManagerScope = true;
IRegionManager detailsRegionManager = detailsRegion.Add(view, null, createRegionManagerScope);
Viewは、ローカル・スコープに更にアクセスするために、新しいRegionManagerを返すAddメソッドを保持することができます。
Viewを作成する
Creating Views
あなたのアプリケーションの視覚的な表示は、少し例を挙げれば、ユーザー・コントロール、カスタム・コントロールとデータ・テンプレートが含まれている多くのフォ-ムを取得することができます。株トレーダーRIの場合には、ユーザー・コントロールは、一般的に、メイン・ウィンドウで異なった項目を表示するために使用されますが、これは標準ではありません。あなたのアプリケーションでは、あなたは、あなたが最も使い慣れている方法を使用する必要があります。そして、それは、あなたが、デザイナーとして、どのように作業するかに合わせます。あなたのアプリケーションの優れている視覚的な表示に関係なく、あなたは、必然的に、全体的なデザインで、ユーザー・コントロール、カスタム・コントロールとデータ・テンプレートの組合せを使用します。次の図は、株トレーダーRIが、これらのさまざまな項目を使用するところを示します。また、この図は、項目の各々を説明する、以降のセクションの基準になります。
ユーザー・コントロール
User Controls
Blend for Visual Studio 2013とVisual Studio 2013の両方は、ユーザー・コントロールを作成するための、高機能なサポートを提供します。これらのツールで作成したユーザー・コントロールは、したがって、PrismライブラリでUIコンテンツを作成するために推奨されます。この話題の初めに触れたように、株トレーダーRIは、広範囲に、領域に挿入する内容を作成するために、それらを使用します。WatchListView.xamlユーザー・コントロールは、WatchModuleの中に含まれている簡単なUIの表示の良い例です。このコントロールは、このモデルを使用して、わかりやすく作成するための、極めて簡単なコントロールです。
ユーザー定義したコントロール
Custom Controls
いくつかの状況では、ユーザーコントロールは、あまりにも制限されています。これらの場合では、カスタムレイアウトや拡張性は、作成の容易さよりも重要です。これは、カスタム・コントロールが役に立つところです。株トレーダーRIでは、円グラフ・コントロールは、これの良い例です。このコントロールは、位置から派生したデータから構成され、そして、全体のポートフォリオのチャートを表示します。この種のコントロールは、作成するユーザー・コントロールに比べて、更に少し挑戦的です。そして、それは、Blend for Visual Studio 2013とVisual Studio 2013で、ユーザー・コントロールと比較して、制限された外観のデザイン・サポートを持っています。
データ・テンプレート
Data Templates
データ・テンプレートは、データ駆動アプリケーションのほとんどの型の重要な部分です。リストに基づいたコントロールのためのデータ・テンプレートの使用は、株トレーダーRIの中で、一般的です。多くの場合、あなたは、どんな型のコントロールも作成する必要なく、完全な外観の表示を作成するために、データ・テンプレートを使用することができます。ResearchRegionは、記事を表示するデータ・テンプレートと提供される項目のスタイルと一緒に、項目が選択されたしるしを使用しています。
Blend for Visual Studio 2013とVisual Studio 2013は、データ・テンプレートのための最大の視覚的なデザイン・サポートを持っています。
リソース
タイル、リソース・ディクショナリとコントロール・テンプレートのようなリソースは、アプリケーションに拡散することができます。これは、特に、複合アプリケーションに当てはまります。あなたが、リソースを、どこに配置するか考えるとき、それらが必要とするUI要素とリソースの間の依存関係に、特別な注意を払います。次の図に示される、株トレーダーRIの解決策は、リソースが存在できる、さまざまな領域を示す、ラベルが含まれています。
アプリケーション・リソース
Application Resources
通常、アプリケーション・リソースは、全体としてアプリケーションが利用できるリソースです。これらのリソースは、ルート・アプリケーションに重点を置く傾向がありますが、また、それらは、モジュールやコントロールの型ごとに、既定のスタイルを提供することができます。この一つの例は、ルート・アプリケーションのテキストボックス型に適用される、テキストボックス・スタイルです。このスタイルは、スタイルが、モジュールや制御レベルで上書きされない限り、アプリケーションで、すべてのテキストボックスが利用できます。
モジュール・リソース
Module Resources
モジュール・リソースは、モジュール内のすべての項目に適用することができる、ルート・アプリケーション・リソースとして、同様の役割を果たします。このレベルの使用しているリソースは、全てのモジュールの中で、一致した外観を提供することができます。そして、また、1つ以上のビジュアル・コンポーネントに及ぶ、より多くの特定のインスタンスで再使用できます。モジュール・レベルでのリソースの使用は、それぞれのモジュールの範囲内に含まれている必要があります。モジュールの間で依存関係を作成すると、UI要素が誤って表示されるとき、配置するのが難しい問題につなげることができます。
コントロール・リソース
Control Resources
コントロール・リソースは、通常、コントロール・ライブラリに含まれています。そして、コントロール・ライブラリ内のすべてのコントロールによって、使用することができます。これらのリソースは、コントロール・ライブラリには、一般的に、極めて特定のコントロールが含まれており、ユーザー・コントロールが、含まれていないため、最も制限した範囲を持っている傾向があります(Prismライブラリで作成されたアプリケーションでは、ユーザー・コントロールは、一般的に、それらが使用されるモジュールで、配置されます)。
UIデザインの手引き
UI Design Guidance
この話題の目標は、PrismライブラリとWPFで、アプリケーションを構築しているXAMLの設計者と開発者にいくつかの高水準の手引きを提供することです。この話題は、UIのレイアウト、視覚的な表示、データ結合、リソースとプレゼンテーション・モデルを説明します。この話題を読んだ後に、Prism Libraryと、あなたが、複合アプリケーションの中で保守しやすいUIを作成するために役に立てる事ができるいくつかの技術に基づいて、あなたは、アプリケーションのUIの設計に、どのようにアプローチするかについての高いレベルの理解が必要です。
ユーザー・インターフェイスを設計するためのガイドライン
ユーザー・インターフェイスを設計するためのガイドライン
Prismライブラリで作成された複合アプリケーションのレイアウトは、WPFの標準原則に基づいています。-レイアウトは、関連する項目が含まれているパネルの概念を使用します。しかしながら、複合アプリケーションでは、さまざまパネル内の内容は、動的で、そして、設計時には、わかっていません。これは、別々にレイアウトに合わせるレイアウトされた内容を、そして、続いて、デザインを、それぞれの要素を含めることができる、ページ構造を作成するために、設計者と開発者に強制します。デザイナーや開発者として、これは、あなたが、Prismライブラリで、2つの中心となるレイアウトの概念について考える必要がることを示しています。:コンテナ構成と領域。
コンテナの構成
Container Composition
コンテナ構成は、実際に、WPFが本質的に提供する格納モデルの拡張です。用語コンテナは、他の要素を含めることができる、ウィンドウ、ページ、ユーザー・コントロール、パネル、カスタム・コントロール、コントロール・テンプレートやデータ・テンプレートが含まれている、どんな要素でも示すことができます。
あなたが、UIを、どのように視覚化するかは、実装から実装まで変化させることができますが、あなたは、際立って、繰り返されているテーマを見つけるでしょう。あなたは、固定された内容と動的なコンテンツの両方が含まれている、ウィンドウ、ページやユーザー・コントロールを作成するでしょう。固定された内容は、UI要素が含まれる全体的な構造から構成され、そして、動的コンテンツは、領域内に配置されるものです。
例えば、WPFの株トレーダーRIは、アプリケーションのための全体的な構造が含まれるShell.xamlという名前のスタートアップ・ウィンドウを持っています。次の図は、Visual Studio 2013のBlendで読み込まれるシェルを示しています。UIの固定部分だけが表示されることに注意してください。モジュールとしてアプリケーションを読み込むことで、さまざまな領域に、シェルの残りの項目は、動的に挿入されます。
設計時の経験は、この種のアプリケーションでは、少し制限されますが、あなたが知っている内容が、実行時に、さまざまな領域に配置する事実は、あなたが、設計するのために必要な何かです。この例を確認するには、その次の図の中で、メインページのデザイナーViewを実行時のViewと比較します。デザイナーViewでは、ページの大部分は空です。それを、位置データを持つTabコントロールが含まれている位置、そして、選択された株に関連するトレンド・ライン、円グラフとニュース分野の領域を実行時のViewと比較します。デザイナーViewと実行時のViewとの違いは、Prismライブラリで構築されるアプリケーションを作成するとき、設計者と開発者が直面する難問を説明します。
項目は、設計時に見ることができません。;その結果、それらが、どれくらい大きいかを決定し、そして、それらが、アプリケーションの全体の外観をどのように合わせるかは、少し難しいです。あなたのコンテナのために、あなたが作成するレイアウトとして、次の点を考慮してください。:
- 大きな内容が制限することができる、どんなサイズ制限が、あるでしょうか?スクロールをサポートするコンテナを使用する場合について考えてみてください。
- 動的な大量のコンテンツが、それを限られた分野に合わせる必要がある状況のためのエキスパンダーとScrollViewerの組合せを使用することについて考えてみてください。
- あなたのアプリケーションの外観が、どんな解像度においても魅力であることを確実にするために、画面の内容が大きくなる従い、どのように拡大するか詳細に注意を払ってください。
Blend for Visual Studio 2013の株トレーダーRIメイン・ウィンドウ
設計時の複合アプリケーションの表示
Viewing Composite Application at Design Time
先程の2つの図は、実行時に構成される、高水準のViewで動作する難問の1つを示します。複合アプリケーションのそれぞれのUI要素は、別々に設計する必要があります。これにより、実行時に複合ページやウィンドウが、どのように表示されるかを視覚化することが難しくなります。その構成された状態で複合Viewを視覚化するために、あなたは、あなたが検証したいViewのための、すべてのUI要素が含まれている、ページやウィンドウでテスト・プロジェクトを作成することができます。
さらに、Blend for Visual Studio 2013とVisual Studio 2013に、データと一緒にUI要素を埋め込むために、設計時のサンプルデータ機能を使用することについて考えてみてください。あなたが、データ・テンプレート、リスト・コントロール、チャートやグラフで作業するとき、設計時のデータは、極めて役に立ちます。詳細については、設計時のサンプルデータのためのガイドラインの項目を参照してください。
レイアウト
Layout
あなたが、複合アプリケーションの配置を設計する時、次の点を考慮してください。:
- シェルは、アプリケーションの中心となるレイアウトを定義します。レイアウトの各々の範囲は、領域で、そして、空のコンテナとして維持される必要があります。内容が実行時に、そこに読み込まれるため、設計時に、領域内に内容を配置しません。
- シェルは、バックグラウンド、タイトルとフッタが含まれている必要があります。シェルをASP.NETのマスター・ページとみなします。
- 領域として動作する制御するコンテナは、それらが含まれるビューから分離されます。その結果、あなたは、コントロールを変更することなく、ビューのサイズを変更することができるはずです。そして、あなたは、ビューを変更することなく、コントロールのサイズを変更することができるはずです。ビューのサイズを定義するとき、あなたは、次に示すことを考慮する必要があります。:
- ビューが、いくつかの領域で使用される場合、あるいは、それが、どこで使用されるか不明である場合、動的な幅と高さで、それを設計します。
- ビューが、固定した大きさを持っている場合、シェルの領域は、動的なサイズを使用する必要があります。
- シェルの領域が、固定した大きさを持っている場合、ビューは、動的なサイズを使用する必要があります。
- ビューは、固定された高さと動的な幅を必要とするかもしれません。この例の一つは、株トレーダーRIのサイドバーに配置されるPositionPieChartビューです。
- 他のビューは、動的な高さと幅**.**を必要とする場合があります。例えば、株トレーダーRIのサイドバーのニュースリーダー・ビューです。高さそのものは、タイトルの長さに依存します。そして、幅は、常に、領域のサイズ(サイドバーの幅)に適応する必要があります。同じことが、グリッドの幅は画面サイズに適合し、高さはグリッドの行の数に適合する必要があります。PositionSummaryViewビューにも、適用されます。
- ビューは、通常、シェルの背景が、アプリケーション視覚的な背景を提供できる透明な背景をもつ必要があります。
- XAMLで、直接、プロパティ値を割り当てるよりはむしろ、常に、色、ブラシ、フォントとフォントサイズを割り当てるために、名前を付けたリソースを使用します。これは、時間の経過とともに、アプリケーションの保守がかなり簡単になります。また、それは、アプリケーションが、実行時に、リソース・ディクショナリの変更に反応できます。
アニメーション
Animation
あなたが、シェルやビューの中で、アニメーションを使用する時、以下の点を考慮してください。:
- あなたは、シェルの配置をアニメーション化できますが、あなたは、別々に、その内容とビューをアニメーション化する必要があります。
- 別々に各々のビューを設計し、アニメーション化します。
- UI要素が、ビューに導入されているか、ビューから削除されているために、視覚的な手掛かりを提供するために、柔らかい、あるいは、穏やかなアニメーションを使用します。これは、アプリケーションに洗練された見た目と感じを与えます。
Blend for Visual Studio 2013は、表示状態変更やイベントに基づくアニメーション化や移行のためのUI要素のために、動作、緩和関数と優れた編集経験の高機能な設定を提供します。詳細については、MSDNの「VisualStateManagerクラス」を参照してください。
実行時の最適化
Run-Time Optimization
処理能力の最適化のために、次のヒントを考慮してください。:
- スタイルが重複することを避けるために、App.xamlファイルや結合されたディレクトリに、共通リソースを配置します。
設計時の最適化
Design-Time Optimizations
次の項目で、ほとんどの設計時の経験を作成するための、設計時の使い方と提供される解決策を説明します。
多くのXAMLリソースをもつ大規模なソリューション
Large Solutions with Many XAML Resources
ソリューションの一部の多くのXAMLリソースを持つ大規模なアプリケーションでは、時々、大幅に、ビジュアル・デザイナーの読込時間に、影響を受けることがあります。ビジュアル・デザイナーが、すべての結合されたXAMLリソースを解析しなければならないため、この処理能力の減速が存在します。この問題を解決するには、すべてのXAMLリソースをもう一つのソリューションに移動し、そのソリューションをコンパイルすることです。そして、その次に、大規模なソリューションから、新しいXAMLリソースDLLを参照します。XAMLリソースが、バイナリを参照するアセンブリであるため、ビジュアル・デザイナーは、XAMLリソースを解析しません。このように、設計時の処理能力を向上させます。外部のアセンブリへXAMLリソースを移動するとき、あなたのリソースのためのComponentResourceKeysを公開することを考えるといいかもしれません。詳細については、MSDNのComponentResourceKeyマークアップ拡張機能を参照してください。
XAMLの資産
XAML Assets
XAMLは、画像、図表、描画と3Dシーンのような、資産を作成するための、強力で表現力豊かな言語です。一部の開発者とデザイナーは、.ico、.jpgや.png画像ファイルを使用する代わりに、XAMLの資産を作成するのを好みます。彼らがXAMLの方法を好む理由の1つは、XAMLのレンダリングの解像度の独立を利用することです。もう一つは、それらが、すべての必要とされる資産を作成し、それらのアプリケーションを設計するための、1つのツールセットBlend for Visual Studio 2013を使用できるということです。
ソリューションが、これらの資産を多く持っている場合、設計時のビジュアル・デザイナー読み込みは、影響を受けるかもしれません。分離したDLLに資産を移動すると、パフォーマンスの問題を解決します。また、資産を移動することで、複数のソリューションの中で再使用できます。
ビジュアル・デザイナーと参照アセンブリ
Visual Designers and Referenced Assemblies
XAMLリソースと資産をバイナリ参照アセンブリへ移動することの残念な副作用は、Blend for 2013そして、Visual Studio 2013プロパティ・エディタは、バイナリ参照アセンブリに配置されるリソースの一覧を示しないことです。これは、あなたが、ツールによって提供されるリソース・ピッカーから、名前を付けたリソースを選択できないことを示しています。その代わりに、あなたは、リソースの名前を分類する必要があります。
デザイナーに親しみやすいビューを作成するためのガイドライン
Guidelines for Creating Designer Friendly Views
また、以下は、blendableやtool-ableとして知られている、デザイナーが親しみやすいアプリケーションの特徴のいくつかです。:
- それは、Visual StudioとBlend designersを使用して、生産的な編集経験を提供します。
- これは、ツーリングに対応しています。例えば、それは、あなたが、バインディング・ビルダーを使用できます。
- 必要な場合には、設計時のサンプルデータを提供します。
- これは、コードに、未処理の例外を発生させることなく、設計時に実行することができます。
次の動作は、編集セッションの間に何度も実行されます。デザイナーに親しみやすくないユーザー・コードは、これらの動作の一つ以上を失敗させます。このように、開発者やデザイナーの生産性と創造力を低下させます。
- デザイン画面動作:
- オブジェクトの構築
- オブジェクトの読み込み
- プロパティ値の設定
- デザイン画面のジェスチャーの実行
- ルート要素としてコントロールを利用する
- 他のコントロールの中にコントロールを格納する
- XAMLファイルを開く、閉じる、そして、再び開く、ことを繰り返す
- プロジェクトを作り直す
- デザイナーを再読み込みする
- バインディング・ビルダーの動作:
- DataContextを発見する
- 利用できるデータ・ソースを一覧にする
- データ・ソース・タイプのプロパティをリスト化する
- 設計時のサンプルデータの動作:
- 適切にサンプルデータを表示するために、デザイン画面でコントロールを使用する
設計時のコーディング
Coding for Design Time
あなたに、豊かな経験を設計時に与えるために、Visual StudioとBlend designersは、オブジェクトのインスタンスを生成し、そして、設計時にコードを実行します。しかしながら、高い割合で読み込みに失敗し、そして、不必要な設計時の例外をもたらす、インスタンスを生成する前に、null参照の例外は、コードで、参照型を呼び出しを試みます。
ユーザー・コードで、避けること | Visual Studio 2013 | Blend for Visual Studio 2013 |
---|---|---|
設計時間に複数のスレッドを回転させる。例えば、設計時間に、コンストラクタやLoadedイベントの中で、インスタンス化し、そして、タイマーを開始します。 | NG | NG |
設計時に、スタック・オーバーフローを引き起こすコントロールを使用します。それら自身を再帰的に読み込むことを試みるために、コントロールを使用します。 | NG | NG |
null参照の例外を、コンバータやデータ・テンプレート・セレクタに投げる。 | NG | NG |
null参照や他の例外をコンストラクタに投げる。これらは、以下の原因で発生します。:
|
NG | NG |
null参照や他の例外をコントロールやユーザー・コントロールのLoadedイベントに投げる。これは、あなたが、実行する時に、trueかもしれませんが、設計時は、trueではないコントロールの状態について仮定するときに生じます。 | NG | NG |
設計時に、アプリケーションやApplication.Currentオブジェクトを呼び出そうと試みる。 | NG | NG |
非常に大規模なプロジェクトを作成する。 | OK | NG |
設計時のユーザー・コードで問題を軽減する
Mitigating Problems in Design-Time User Code
いくつかの実行できる防御的なコーディングは、前述の表で説明される問題のほとんどを取り除きます。しかしながら、あなたが、設計時のユーザー・コードで問題を軽減することができる前に、あなたは、分離した設計者によって、初期化されていないアプリケーション・ドメインの中で、あなたのアプリケーション・コントロールとコードが実行されていることを理解している必要があります。この場合、初期化は、通常の起動、ブートストラップや初期化コードが実行されていないことを示しています。
実行時に、あなたのアプリケーションが実行されるとき、App.xaml.csやApp.xaml.vbのスタートアップ・コードが、実行されます。あなたが、そこに、あなたのアプリケーションの残りに依存するコードを持っている場合、このコードは、設計時に、実行されていないでしょう。あなたが、このあなたのコードで、予想していない場合、不必要な例外が、発生します。(そういうわけで、設計時に、ユーザー・コードで、ApplicationやApplication.Currentオブジェクトを呼び出そうとすると、結果として例外が生じます)。これらの問題を軽減するために、:
- 参照されたオブジェクトが、設計時のコードで、インスタンスを生成することを全く想定していません。設計時に、実行できるコードでは、常に、どんな参照オブジェクトでも呼び出す前に、nullの検査を実行します。
- あなたのコードが、ApplicationやApplication.Currentオブジェクトを呼び出す場合、オブジェクトを呼び出す前に、null参照の確認を実行します。
- あなたのコンストラクタや読み込んだイベントハンドラが、複雑なコードやデータベースにアクセスする、あるいは、ネットワークを呼び出すコードを実行する必要がある場合、次の解決策を考慮します。:
- System.ComponentModel DesignerPropertiesメソッド、DesignerProperties.GetIsInDesignModeを呼び出すことによって、コードが設計時に、実行している場合、判断する検査の内側のコードをラップします。
- コンストラクタやLoadedイベントハンドラで直接コードを実行する代わりに、インターフェイスの背後にあるクラスの呼び出しを抽象化します。そして、その次に、設計時の、実行時の、そして、テスト時のそれぞれの依存関係を解決するために、多くの技術のうちの1つを使用します。
例えば、データを取り出すために、直接、データサービスに呼び出す代わりに、データサービスの呼び出しをクラスでラップします。それは、インターフェイスを通してメソッドを公開しています。そして、設計時にモックや設計時のオブジェクトで、インターフェイスを解決します。
設計時に、ユーザー・コントロール・コードが実行されるときを理解する
Understanding when User Control Code Executes at Design-Time
BlendとVisual Studioは、デザイナーの枠に表示されるルート・オブジェクトのモックアップを使用します。これは、必要とされるデザイン経験を提供することが必要です。ルート・オブジェクトが、モックのため、そのコンストラクタとLoadedイベント・コードは、設計時には、実行されません。しかしながら、シーンの残りのコントロールは、通常、構築されています。そして、それらのLoadedイベントは、実行時に、ちょうど今のように、発生させられます。
次の説明では、ルートWindowsコンストラクタとLoadedイベント・コードは、実行されません。子のユーザー・コントロール・コンストラクタとLoadedイベント・コードは、実行されます。
これらの概念は、特に、あなたが、複合アプリケーションや実行時に動的に構築されるアプリケーションを構築している場合、重要です。
ほとんどのアプリケーション・ビューは、コード化されて、独立して設計されます。それらが、独立して設計されるため、それらは、一般的にデザイナーのルート・オブジェクトです。このため、それらのコンストラクタとLoadedイベント・コードは、決して実行されません。
しかしながら、あなたが、他のコントロールの子として、その同じユーザー・コントロールを取得して、それをデザイン画面に配置する場合、一度、分離されたユーザー・コントロール・コードは、現在、設計時に実行されません。あなたが、設計時のコードの問題を緩和するために、上記の慣行に従わなかった場合、次に、格納されたユーザー・コントロールは、不親切になり、そして、デザイナーの読込問題を引き起こします。
設計時のプロパティ
Design-Time Properties
組み込みの「d:」設計時のプロパティは、良好な設計時のツールでのツーリング経験への平坦な道を提供します。
私たちが解決する必要がある問題は、設計時に、バインディング・ビルダー・ツールに形状を、どのように提供するかです。この場合、形状は、バインディング・ビルダーがリフレクトを有効にできる、そして、その次に、バインディングを構築するとき、選択のために、それらのプロパティの一覧を示すインスタンス化された型です。
また、形状は、設計時にサンプルデータで、提供されます。サンプルデータは、設計時のサンプルデータのためのガイドラインの項目で取り扱われます。
次のセクションでは、d:DataContextプロパティとd:DesignInstanceマークアップ拡張機能を、どのように、使用するかを説明します。
プロパティの中の「d:」とマークアップ拡張機能は、designプロパティがメンバーであるdesign名前空間のための別名です。より詳細な情報は、MSDNトピックのWPFデザイナーの設計時の属性を参照してください。
「d:」プロパティとマークアップ拡張機能は、ユーザー・コードで、作成、あるいは、拡張できません。延長しました;それらは、XAMLでのみ使用することができます。「d:」プロパティとマークアップ拡張機能は、あなたのアプリケーションにコンパイルしません。; それらは、Visual StudioとBlendツーリングでのみ使用されます。
d:DataContextプロパティ
d:DataContext Property
d:DataContextは、コントロールとその子供たちのために、設計時のデータ・コンテクストを指定します。d:DataContextを指定するとき、あなたは、常に、実行時のDataContextとして、設計時のDataContextに同じ形状を提供する必要があります。
DataContextとd:DataContextの両方がコントロールのための指定される場合、ツーリングは、d:DataContextを使用するでしょう。
d:DesignInstanceマークアップ拡張機能
d:DesignInstance Markup Extension
マークアップ拡張機能が、あなたにとって新しい場合、MSDN上で、マークアップ拡張機能とWPFのXAMLをお読みください。
d:DesignInstanceは、デザイナーのコントロールに結合するためのデータ・ソースとして、あなたが割り当てることを望むインスタンス化したType ("shape")を返します。タイプは、形状を確立するために使用されるために作成可能な必要はありません。次の表は、d:DesignInstanceマークアップ拡張機能プロパティについて説明します。
マークアップ拡張機能プロパティ | 定義 |
---|---|
Type | Typeの名前は作成されるでしょう。Typeは、コンストラクタの既定のパラメータです。 |
IsDesignTimeCreatable | 指定されたTypeは、作成されることができますか?falseの場合、にせのTypeは、現実のTypeと比較して作成されるでしょう。既定では、falseです。 |
CreateList | trueの場合、指定されたTypeの一般的なリストを返します。既定では、falseです。 |
代表的なd:DataContextの筋書き
Typical d:DataContext Scenario
次の3つのコードの例は、ViewとView Modelを接続し、デザイナーのツーリングを有効にするための反復可能なパターンを説明します。
PersonViewModelは、PersonViewが実行時の依存関係です。例のビュー・モデルは、信じられないほど簡単ですが、現実世界のビュー・モデルは、一般的に、解決する必要がある1つ以上の外部依存関係を持っています。そして、それらの依存関係は、一般的に、それらのコンストラクタに注入します。
PersonViewが、構築されるとき、その依存関係PersonViewModelは、MEFや依存関係注入コンテナで、構築され、そして、その依存関係は解決します。
備考 View Modelが、解決するために必要な外部の依存関係を持っていない場合、View Modelは、ViewのXAMLで、インスタンスを生成することができ、そして、そのDataContextとd:DataContextは、必要ありません。
// PersonViewModel.cs
[Export]
public class PersonViewModel
{
public String FirstName { get; set; }
public String LasName { get; set; }
}
// PersonView.xaml.cs
[Export]
public partial class PersonView : UserControl
{
public PersonView()
{
InitializeComponent();
}
[Import]
public PersonViewModel ViewModel
{
get { return this.DataContext as PersonViewModel; }
set { this.DataContext = value; }
}
}
これは、ViewとView Modelを接続することのための優れたパターンです。;しかしながら、それは、設計時に、そのDataContextの形状(View Model)を知らないViewを残します。
次のXAMLの例では、あなたは、PersonViewModelのにせのインスタンスを返すために、グリッドで使用されるd:DesignInstanceマークアップ拡張機能を確かめることができ、それは、続いて、d:DataContextで公開されます。その結果、Gridのすべての子のコントロールは、型とプロパティを発見し、そして、使用するために、デザイナー・ツーリングを有効にするd:DataContextを継承する結果として、開発者とデザイナーのための、より生産的なデザイン経験が、得られます。
<!--PersonView.xaml -->
<UserControl
xmlns:local="clr-namespace:WpfApplication1"
x:Class="WpfApplication1.PersonView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Border BorderBrush="LightGray" BorderThickness="1" CornerRadius="10" Padding="10">
<Grid d:DataContext="{d:DesignInstance local:PersonViewModel}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="First Name" />
<Label Grid.Column="0" Grid.Row="1" Content="Las Name" />
<TextBox
Grid.Column="1" Grid.Row="0" Width="150" MaxLength="50"
HorizontalAlignment="Left" VerticalAlignment="Top"
Text="{Binding Path=FirstName, Mode=TwoWay}" />
<TextBox
Grid.Column="1" Grid.Row="1" Width="150" MaxLength="50"
HorizontalAlignment="Left" VerticalAlignment="Top"
Text="{Binding Path=LasName, Mode=TwoWay}" />
</Grid>
</Border>
</UserControl>
備考:添付プロパティとViewModelロケーター・ソリューション
Note: Attached Property and ViewModel Locator Solution
開発者コミュニティから利用可能なViewとView Modelを関連付けるための、いくつかの代わりの技術があります。1つの難問は、実行時の、その大きな操作は、常に、設計時には、操作しないソリューションです。そのようなソリューションの一つは、ViewのDataContextを割り当てる添付プロパティとView Modelロケーターを使用することです。View Modelを構築することができ、その依存関係を解決することができるように、View Modelロケーターが、必要です。
また、この問題の解決策は、あなたが、d:DataContextを含める必要があることです。-この方法で、添付プロパティの結果をビジュアル・デザイナー・ツーリングが、反映することができないため、d:DesignInstanceの組合せは、d:DesignInstanceと一緒にできます。
設計時に、形状を解決することのため、あなたのアプリケーションで、その技術を実装するかどうかに関係なく、最も重要な目標は、あなたのアプリケーションを通して一貫していることです。一貫性は、アプリケーションの保守を遥かに簡単にします。そして、うまくいく、デザイナー - 開発者作業の流れに導きます。
設計時のサンプルデータのためのガイドライン
Guidelines for Design-Time Sample Data
WPFとSilverlightデザイナー・チームは、詳細なものを公開しました。筋書きに基づいたトレーニング記事は、WPFとSilverlightプロジェクトで、サンプルデータの使用について説明します。WPFとSilverlightデザイナーのサンプルデータの記事は、MSDNで利用可能です。
設計時のサンプルデータを使用する
Using Design-Time Sample Data
あなたが、BlendやVisual Studio 2013のような、ビジュアル・デザイン・ツールを使用する場合、設計時のサンプルデータは、極めて重要になります。Viewは、データと画像に埋め込むことができます。デザイン・タスクをより簡単に、そして素早く達成するために、作成します。これは、生産性の向上と創造性をもたらします。
データ・テンプレートが含まれる空きリスト・コントロールは、それらがデータに埋め込まれない限り、表示されません。空のコントロールを編集するタスクを作成することは、あなたが、実行時に、どのように編集したか確かめるために、アプリケーションを実行する必要があるため、より多くの時間を消費します。
サンプル・データ・ソース
Sample Data Sources
あなたは、どんな、次のソースのサンプルデータでも使用することができます。:
- Blend for Visual Studio 2013 XMLのサンプルデータ
- Blend for Visual Studio 2013とVisual Studio 2013 XAMLのサンプルデータ
- XAMLリソース
- コード
これら各々のソースのデータは、次のサブセクションに記述されています。
Blend XMLサンプル・データ
Blend XML Sample Data
Blendは、あなたに、XMLスキーマーをすばやく作成する、そして、対応するXMLファイルを埋め込むを能力を与えます。これは、どんなプロジェクト・クラス上で、どんな依存関係もなしで達成されます。
この種のサンプルデータの目的は、開発者のために待つこと無く、あるいは、アプリケーション・クラスの消費が可能になる前に、デザイナーが、すばやくそれらのプロジェクトを開始できます。
ほとんどのサンプルデータが、BlendとVisual Studioデザイナーの両方でサポートされていますが、XMLサンプルデータは、Blendの機能です。そして、Visual Studioデザイナーで、レンダリングしません。
備考: XMLサンプル・データ・ファイルは、構築されるとき、コンパイルされない、あるいは、アセンブリに追加されません。;しかしながら、XMLスキーマーは、構築されたアセンブリにコンパイルされます。
Blend for Visual Studio 2013とVisual Studio 2013 XAMLのサンプルデータ
Blend for Visual Studio 2013 and Visual Studio 2013 XAML Sample Data
Expression Blend 4とVisual Studio 2010から始まる、d:DesignDataマークアップ拡張機能は、XAMLのサンプルデータの設計時の読み込みを有効にするために、追加されました。
サンプルデータのXAMLファイルは、1つ以上の型のインスタンスを生成し、そして、値をプロパティに割り当てるXAMLが含まれています。
d:DesignDataは、プロジェクトで配置されるサンプルデータXAMLファイルに、統一資源識別子(URI)を取得するSourceプロパティを持っています。d:DesignDataマークアップ拡張機能は、XAMLファイルを読み込んで、それを解析して、続いてオブジェクト・グラフを返します。オブジェクト・グラフは、d:DataContextプロパティ、CollectionViewSource d:DesignSource propertyやDomainDataSource d:DesignDataプロパティで利用することができます。
d:DesignDataマークアップ拡張機能が解決する難問の1つは、それが、ユーザーが作成できない型のサンプルデータを作成きることです。例えば、WCF Rich Internet Application (RIA) Services entity-派生したオブジェクトは、コードの中で作成することができません。加えて、開発者は、作成可能ではない、それら独自の型があるかもしれませんが、まだ、これらの型のサンプルデータを持っていると思います。
あなたは、。以下のように、ソリューション・エクスプローラー内の、サンプルデータ上のBuild Actionプロパティを設定することで、:DesignDataが、どのようにあなたのサンプル・データ・ファイルを処理するか、変更することができます:
- Build Action = DesignData - フェイクタイプが、作成されるでしょう。
- Build Action = DesignDataWithDesignTimeCreatableTypes - 現実のタイプが、作成されるでしょう。
Blendが、クラスのためのサンプルデータを作成するために使用されるとき、それは、Build Actionセットで、XAMLのサンプル・データ・ファイルをDesignDataへ作成します。あなたが、現実のタイプを必要とする場合、Visual Studioでソリューションを開き、そして、サンプル・データ・ファイルのために、Build ActionをDesignDataWithDesignTimeCreatableTypesに変更します。
備考: 次の図の中で、Custom Toolプロパティは空です。これは、適切に動作するサンプルデータのために必要です。既定では、Blendは、適切に、このプロパティを空に設定します。
あなたが、サンプル・データ・ファイルを追加するために、Visual Studio 2013を使用すると、あなたは、一般的に、新しいリソース・ディクショナリの項目を追加し、それらを編集します。この場合、あなたは、Build Actionを設定し、そして、CustomToolプロパティをクリアする必要があります。
Expression Blendは、すばやく作成するためのツーリングと結合されたXAMLのサンプルデータを提供します。次の図に示すように、XAMLのサンプルデータは、Visual Studio 2013デザイナーで、使用することができ、そして、見ることができます。
あなたは、続いて、Viewのルート要素上に、ドラッグすることができます。UserControlのような、そして、それを、d:DataContextプロパティに設定します。あなたは、アイテム・コントロールの上に、サンプル・データ・コレクションをドロップすることもできます。そして、Blendは、コントロールにサンプルデータを接続するでしょう。
備考: XAMLのサンプル・データ・ファイルは、構築されたアセンブリに、コンパイルされない、あるいは、含まれていません。
XAMLのリソース
XAML Resource
あなたは、目的とする型のインスタンスを生成するXAML内に、リソースを作成する、そして、その次に、そのリソースを、DataContextやリスト・コントロールに結合することができます。
この技術は、すばやく、サンプルデータなしで編集するより、長い時間がかかる、データ・テンプレートを編集するために使用される使い捨てのサンプルデータを作成するために、使用することができます。
コード
Code
あなたが、コードの中で、サンプルデータを作成することを好む場合、あなたは、利用者へサンプルデータを返す、プロパティやメソッドを公開するクラスを記述することができます。例えば、あなたは、その既定の空のコンストラクタに、Customerクラスの複数のインスタンスで、それ自体を埋め込んだCustomersクラスを記述することができました。また、各々のCustomerインスタンスは、適切なプロパティの値セットがあります。
あなたが、利用するために、以前に説明したサンプルデータ・クラスを使用できる1つの技術は、使用するために、d:DataContext、d:DesignInstanceを組合せ、d:DesignInstance IsDesignTimeCreatableプロパティをTrueに設定することを確認することです。 IsDesignTimeCreatableをTrueにする必要がある理由は、あなたが、顧客コンストラクタが実行したいため、コードは、クラスに埋め込まれ、実行されます。顧客が、フェイクタイプとして扱われている場合、顧客コードは、実行されることはありません。そして、「形状」だけは、ツーリングによって発見できます。
次のXAMLの例は、Customersクラスのインスタンスを生成します。そして、その次に、d:DataContextとして、それを設定します。このグリッドの子のコントロールは、顧客クラスによって公開されているデータを利用することができます。
UIのレイアウトの重要な決定事項
UI Layout Key Decisions
あなたは、複合アプリケーション・プロジェクトを開始するとき、後で変更するのが難しい、作成する必要がある幾つかのUIの設計上の決定があります。通常、これらの決定は、アプリケーションに広範囲に、そして、それらの一貫性を開発者とデザイナー生産性に支援します。
以下は、重要なUIレイアウトの結論です。:
- アプリケーションの流れを決定して、それに対応して領域を定義します。
- それぞれの領域が、使用するViewのタイプを読み込むかを決定します。
- あなたが、領域ナビゲーションAPIを使用するかどうかを決定します。
- あなたが、どのUIデザイン・パターン(MVVM、プレゼンテーション・モデル、その他)を使用するかを決定します。
- サンプルデータ戦略を決定します。
詳細情報
More Information
- Prismライブラリを拡張する方法の詳細については、Prismライブラリを拡張するを参照してください。
- コマンドの詳細については、「MVVMパターンを実装する」の「コマンド」を参照してください。
- データ結合の詳細については、「MVVMパターンを実装する」の「データ結合」を参照してください。
- 領域ナビゲーションの詳細については、ナビゲーションを参照してください。
このトピックで説明されるガイドラインの詳細については、以下を参照してください。:
- MSDNの依存関係プロパティの概要。
データ結合; 以下を参照してください。:
- MSDNのデータ結合の概要。
- MSDN MagazineのWPFのデータ結合。
- MSDNのデータ・テンプレートの概要。
- MSDNのリソース概要。
- MSDNのUserControlクラス。
- MSDNのVisualStateManagerクラス。
- MSDNマガジンの、Windows Presentation Foundationのためのコントロールをカスタマイズする。
- MSDNのComponentResourceKeyマークアップ拡張機能。
- MSDNの設計時のWPFデザイナーの属性。
- MSDN上のマークアップ拡張機能とWPFのXAML。
- Visual StudioのWPFとSilverlight Designerを学ぶ。
チュートリアルと記事には、レイアウト、リソース、データ結合、サンプルデータ、データ結合のデバッグ、オブジェクト・データ・ソース、と詳細なフォームの内容が含まれています。