目次
- はじめに
- Prismアプリケーションの初期化
- コンポーネント間の依存関係の管理
- モジュラーアプリケーション開発
- MVVMパターンの実装
- 高度なMVVMシナリオ
- ユーザーインターフェイスの作成
- ユーザーインターフェイスのガイドライン
- ナビゲーション
- ビューベースのナビゲーション
- 疎結合コンポーネント間の相互作用
Model-View-ViewModel (MVVM、
View-View-View- Model)パターンは、ユーザーインターフェースからビジネスロジックとプレゼンテーションロジックを分離するのに役立ちます。 アプリケーションロジックとUIの間で責任を共有するためのサポートにより、アプリケーションのテスト、保守、開発が容易になります。 また、コードの再利用機能を大幅に向上させ、開発者と設計者がアプリケーションの関連部分の開発でより簡単に共同作業できるようにします。
MVVMパターンを使用すると、アプリケーションユーザーインターフェイス、プレゼンテーションロジック、およびビジネスロジックが3つの個別のクラスに分割されます。 これは、UIとそのロジックをカプセル化するビュー、プレゼンテーションロジックとその状態をカプセル化するビューモデル、およびアプリケーションのビジネスロジックとデータをカプセル化するモデルです。
Prismには、SilverlightまたはWPFアプリケーションでMVVMパターンを実装する方法を示すサンプルおよび実装例が含まれています。 Prismライブラリは、このパターンの実装に役立つ機能も提供します。 これらの機能は、MVVMパターンを実装するための最も一般的な方法を具体化し、Expression BlendおよびVisual Studioとのテスト容易性および互換性を提供するように設計されています。
この章では、MVVMパターンの概要とその実装方法について説明します。 第6章では、Prismライブラリを使用してより複雑なMVVMスクリプトを実装する方法について説明します。
責任とクラスの特徴
MVVMパターンは、
プレゼンテーションモデルパターンの密接なバリエーションであり、データバインディング、データパターン、コマンド、動作などの基本的なWPFおよびSilverlight機能との整合性を高めるために最適化されています。
MVVMパターンでは、ビューはUIとUIロジックをカプセル化し、ビューモデルはプレゼンテーションロジックとその状態をカプセル化し、モデルはビジネスロジックとデータをカプセル化します。 ビューは、データ、コマンド、および通知イベントをバインドすることにより、ビューモデルと対話します。 プレゼンテーションモデルは、モデルにデータを要求するか、変更の通知をサブスクライブし、モデルの状態の更新を調整し、必要に応じてデータを変換、検証、集計してビューに表示します。
次の図は、MVVMパターンの3つの部分とそれらの相互作用を示しています。

すべての共有プレゼンテーションパターンと同様に、MVVMパターンを効率的に使用するための鍵は、アプリケーションコードを正しいクラスに分割する方法を理解し、これらのクラスが異なるシナリオで相互作用する方法を理解することです。 以下のセクションでは、MVVMパターンの各クラスの責任と特性について説明します。
クラスを見る
ビューは、ユーザーが画面に表示するものを決定する役割を果たします。 理想的には、分離コードビューには、
InitializeComponent
メソッドを呼び出すコンストラクターのみが含まれています。 場合によっては、分離コードには、複雑なアニメーションなど、XAMLで表現することが困難または非効率的な視覚的動作を実装するUIロジックコードが含まれている場合があります。また、ビューの一部である視覚要素をコードで直接制御する必要がある場合もあります。 ビューにテストが必要なロジックコードを配置することは許可されません。 通常、コードビハインドビューのコードは、UIオートメーションを使用してテストできます。
SilverlightおよびWPFでは、ビュー内のデータバインディング式は、そのデータコンテキストに関連して評価されます。 MVVMでは、プレゼンテーションモデルはプレゼンテーションデータのコンテキストとして設定されます。 ビューモデルは、ビューをバインドできるプロパティとコマンドを実装し、変更通知イベントを通じて状態の変化をビューに通知します。 通常、ビューとそのプレゼンテーションモデルの間には直接的な関係があります。
通常、ビューは
Control
クラスまたは
UserControl
クラスから継承されます。 ただし、場合によっては、プレゼンテーションは、オブジェクトを視覚的に表すために使用されるUI要素を定義するデータテンプレートによって表される場合があります。 開発者はデータテンプレートを使用して、プレゼンテーションモデルの視覚化方法を簡単に指定したり、基になるオブジェクトやその動作を直接変更せずにデフォルトの視覚表現を変更したりできます。
データテンプレートは、コードビハインドのないビューと見なすことができます。 UIにマップする必要があるときに、特定の種類のプレゼンテーションモデルにバインドするように設計されています。 実行時に、テンプレートによって定義されたビューが自動的に作成され、対応するビューモデルがそのデータコンテキストによって設定されます。
WPFでは、データテンプレートをアプリケーションレベルのビューモデルに関連付けることができます。 次に、WPFは、UIに表示されるたびに、指定されたタイプのプレゼンテーションモデルのオブジェクトにこのデータテンプレートを自動的に適用します。 これは、暗黙的なデータパターンとして知られています。 Silverlightでは、表示するコントロール内のビューモデルオブジェクトのデータテンプレートを明示的に定義する必要があります。 データテンプレートは、それを使用するコントロールに組み込まれているものとして定義するか、親ビューの外部のリソースディクショナリで定義し、プレゼンテーションリソースディクショナリと宣言的に組み合わせることができます。
要約すると、ビューには次の重要な特性があります。
- ビューは、ウィンドウ、ページ、ユーザーコントロール、データテンプレートなどの視覚要素です。 ビューは、コントロール、そのレイアウト、およびスタイルを定義します。
- ビューは、
DataContext
プロパティを介してビューモデルを参照します。 ビュー内のコントロールは、ビューモデルのプロパティとコマンドに関連付けられています。 - ビューは、ビューとビューモデルの間のデータバインディング動作をカスタマイズできます。 たとえば、ビューは値コンバーターを使用してUIに表示されるデータをフォーマットしたり、検証規則を使用してユーザー入力の追加検証を提供したりできます。
- ビューは、アニメーションや遷移などのUIの視覚的な動作を定義および処理します。これは、ビューモデルの状態の変化によって、またはUIとのユーザーインタラクションによってトリガーできます。
- コードビハインドビューは、XAMLで表現するのが難しい、またはビューで定義された特定のUIコントロールへの直接参照を必要とする視覚的な動作を実装するUIロジックを定義できます。
モデルクラスを表示
MVVMパターンのプレゼンテーションモデルは、プレゼンテーションロジックと表示用のデータをカプセル化します。 彼女は、プレゼンテーションへの直接的なリンク、または実装またはプレゼンテーションの種類に関する知識を持ちません。 ビューモデルは、ビューがデータをバインドできるプロパティとコマンドを実装し、通知イベントを通じて状態の変化をビューに通知します。 ビューモデルが提供するプロパティとコマンドは、UIが依存する機能を決定しますが、ビューはその機能がユーザーにどのように表示されるかを決定します。
ビューモデルは、ビューと必要なモデルクラスとの相互作用を調整します。 多くの場合、プレゼンテーションモデルとモデルクラスの間には1対多の関係があります。 ビューモデルは、ビュー内のコントロールがデータをモデルに直接バインドできるように、モデルクラスをビューに直接置き換えることができます。 この場合、モデルクラスは、データバインディングおよび関連する変更通知イベントをサポートするように設計する必要があります。 このシナリオの詳細については、このトピックの「データバインディング」セクションを参照してください。
ビューモデルでは、モデルデータを簡単に使用できるように、モデルデータを変換または操作できます。 ビューモデルには、ビューの特定のニーズに合わせて追加のプロパティがあります。 これらのプロパティは通常、モデルの一部にすることはできません。 たとえば、ビューモデルは2つのフィールドの値を組み合わせて表示しやすくしたり、文字列の長さが制限されているフィールドに入力するときに残っている文字数を計算したりできます。 ビューモデルは、データ検証ロジックを実装して一貫性を確保することもできます。
ビューモデルは、UIの視覚的な変更にビューが使用できる論理状態も決定できます。 ビューは、ビューモデルの状態を反映するマークアップまたはスタイルの変更を定義できます。 たとえば、ビューモデルには、データが非同期的にWebサービスに送信されることを示す状態があります。 この状態では、ビューにアニメーションが表示され、ユーザーに視覚的なフィードバックが提供されます。
通常、プレゼンテーションモデルは、UIで表され、ユーザーが呼び出すことができるコマンドまたはアクションを定義します。 典型的な例は、ユーザーがWebサービスまたはリポジトリにデータを渡すことができる
Submit
コマンドをビューモデルが提供する場合です。 ビューはこのコマンドをボタンとして表示できるため、ユーザーはこのコマンドをクリックしてデータを転送できます。 通常、コマンドが使用できなくなると、UIに関連付けられた表現が無効になります。 コマンドを使用すると、ユーザーアクションをカプセル化し、視覚的なプレゼンテーションから分離できます。
その結果、プレゼンテーションモデルには次の重要な特徴があります。
- これはビジュアルクラスではなく、WPFまたはSilverlightの基本クラスを継承しません。 これは、アプリケーションでのユーザーアクションをサポートするために必要なプレゼンテーションロジックをカプセル化します。 プレゼンテーションモデルは、プレゼンテーションおよびモデルとは独立してテストされます。
- 通常、ビューを直接参照しません。 ビューがデータをバインドできるプロパティとコマンドを実装します。
INotifyPropertyChanged
およびINotifyCollectionChanged
通知イベントを通じて、状態の変化をビューに通知しINotifyCollectionChanged
。 - ビューとモデルの相互作用を調整します。 ビューで簡単に使用できるようにデータを変換または操作できます。また、モデルには存在しない追加のプロパティを実装できます。
IDataErrorInfo
またはINotifyDataErrorInfo
介してデータ検証を実装することもできINotifyDataErrorInfo
。 - ビューがユーザーに視覚的に提示できる論理状態を識別できます。
ご注意 プレゼンテーションまたはプレゼンテーションモデル?
多くの場合、特定の機能を実装する場所を決定することは明らかではありません。 一般的なルールでは、特定のビジュアルディスプレイに関連し、後でアップグレードできるものはすべて(現在、アップグレードを計画していない場合でも)ビューに入れる必要があります。 アプリケーションロジックにとって重要なものはすべて、ビューモデルに入る必要があります。 さらに、ビューモデルにはビュー内の特定の視覚要素に関する明示的な知識がないため、ビュー内の視覚要素をプログラムで制御するためのコードは、ビューのコードビハインドにあるか、 Behaviorsにカプセル化されている必要があります。 同様に、データバインディングによってビューに表示する必要のあるデータ要素を取得または操作するためのコードは、ビューモデルに存在する必要があります。 たとえば、リストボックスで選択したアイテムのハイライト色はビューで定義する必要がありますが、表示するアイテムのリストと選択したアイテムへのリンクはプレゼンテーションモデルで定義する必要があります。
モデルクラス
MVVMパターンのモデルは、ビジネスロジックとデータをカプセル化します。 ビジネスロジックは、データの一貫性と有効性を確保するためにビジネスルールが満たされていることを確認するために、アプリケーションデータの取得と管理に関係するアプリケーションロジックとして定義されます。 再利用性を最大にするために、モデルにはプレゼンテーション固有の情報、ロジック、または動作を含めないでください。
原則として、モデルはアプリケーションのクライアント部分のサブジェクト領域の本質を表します。 アプリケーションデータモデルと、ビジネスおよび検証ロジックに基づくデータ構造を含めることができます。 モデルはデータとキャッシュにもアクセスできますが、これは通常、個別のデータリポジトリまたは対応するサービスを使用して行われます。 多くの場合、モデルおよびデータアクセス層は、ADO.NET Entity Framework、WCF Data Services、またはWCF RIA Servicesインフラストラクチャの一部として自動的に生成されます。
通常、モデルには、ビューへのバインドを容易にするツールが実装されています。 これは通常、プロパティまたはコレクションへの変更の通知が
INotifyPropertyChanged
および
INotifyCollectionChanged
介してサポートされることを意味し
INotifyCollectionChanged
。 オブジェクトのセットを提供するモデルクラスは、通常、
INotifyCollectionChanged
インターフェイスの実装を提供する
ObservableCollection<T>
クラスから継承されます。 モデルは、
IDataErrorInfo
(または
INotifyDataErrorInfo
)インターフェイスを介したデータ検証とエラーレポートもサポートできます。 これらのインターフェイスにより、バインドされたデータの値が変更されたときに、WPFおよびSilverlight通知を送信してUIを更新できます。 また、UIレベルでのデータ検証サポートとエラーレポートも提供します。
ご注意
, ?
インターフェイスINotifyPropertyChanged
、 INotifyCollectionChanged
、 IDataErrorInfo
、またはINotifyDataErrorInfo
実装しないモデルオブジェクトを使用する必要がある場合があります。 これらの場合、ビューモデルはモデルオブジェクトをラップし、ビューに必要なプロパティを提供する必要があります。 これらのプロパティの値は、モデルオブジェクトによって直接提供されます。 ビューモデルは、ビューがデータを簡単にバインドできるように、提供するプロパティに必要なインターフェイスを実装できます。
このモデルには、次の主要な機能があります。
- モデルクラスは、アプリケーションデータとビジネスロジックをカプセル化するビジュアルクラスではありません。 彼らは、必要なビジネスルールとデータ検証ロジックをカプセル化することにより、アプリケーションデータを管理し、その一貫性と有効性を保証する責任があります。
- モデルクラスは、プレゼンテーションクラスまたはプレゼンテーションモデルを直接参照せず、これらのクラスの実装方法に依存しません。
- モデルクラスは通常、プロパティまたはコレクションへの変更の通知を
INotifyPropertyChanged
およびINotifyCollectionChanged
介してINotifyCollectionChanged
。 これにより、プレゼンテーションに簡単に添付できます。 オブジェクトのコレクションを表すモデルクラスは、通常ObservableCollection<T>.
クラスから継承されObservableCollection<T>.
- モデルクラスは通常、
IDataErrorInfo
またはINotifyDataErrorInfo
介してデータ検証とエラーレポートを提供しINotifyDataErrorInfo
。 - モデルクラスは通常、データアクセスとキャッシュをカプセル化するサービスまたはリポジトリで使用されます。
クラスの相互作用
MVVMパターンは、アプリケーションのユーザーインターフェイス、プレゼンテーションロジック、ビジネスロジックとデータの間で責任を明確に分離し、各要素を個別のクラスに分割します。 したがって、MVVMを実装する場合、前のセクションで説明したように、コードを正しいクラスに分割することが重要です。
適切に設計されたプレゼンテーションクラス、プレゼンテーションモデル、およびモデルは、正しいロジックと動作をカプセル化するだけでなく、データバインディング、コマンド、およびデータ検証インターフェイスを通じて簡単に相互作用するように設計されます。
プレゼンテーションとそのプレゼンテーションモデルとの相互作用はおそらく最も重要ですが、モデルクラスとプレゼンテーションモデルとの相互作用も重要です。 以下のセクションでは、これらの相互作用のさまざまなタイプについて説明し、MVVMパターンを実装してそれらを開発する方法について説明します。
データバインディング
データバインディングは、MVVMパターンで非常に重要な役割を果たします。 WPFおよびSilverlightは、強力なデータバインディング機能を提供します。 プレゼンテーションモデルと(理想的には)モデルクラスは、データバインディングをサポートするように設計する必要があります。 通常、これは、正しいインターフェースを実装する必要があることを意味します。
SilverlightおよびWPFデータバインディングは、さまざまなモードをサポートしています。 一方向のデータバインディングを使用すると、UIコントロールをビューモデルに関連付けて、レンダリング時に基になるデータの値を反映させることができます。 双方向データバインディングは、ユーザーがUIでデータを変更すると、基になるデータを自動的に更新します。
プレゼンテーションモデルでデータが変更されたときにUIが更新されるようにするには、適切な変更通知インターフェイスを実装する必要があります。 データをバインドできるプロパティを定義する場合は、
INotifyPropertyChanged
インターフェイスを実装する必要があります。 ビューモデルがコレクションを表す場合、
INotifyCollectionChanged
を実装するか、このインターフェイスを実装する
ObservableCollection<T>
クラスから継承する必要があります。 これらのインターフェースは両方とも、基礎となるデータが変更されるたびに生成されるイベントを定義します。 これらのイベントが生成されると、関連するコントロールが自動的に更新されます。
多くの場合、ビューモデルにはオブジェクトを返すプロパティが含まれています(オブジェクトには、追加のオブジェクトを返すプロパティが含まれている場合があります)。 データバインディングWPFおよびSilverlightは、
Path
プロパティを介したネストされたプロパティへのバインディングをサポートしています。 したがって、プレゼンテーションモデルは、他のクラスのプレゼンテーションモデルまたはモデルへの参照を返す傾向があります。 プレゼンテーションに使用できるすべてのプレゼンテーションモデルクラスとモデルは、
INotifyPropertyChanged
または
INotifyCollectionChanged
実装する必要があり
INotifyCollectionChanged
。
以下のセクションでは、MVVMパターン内のデータバインディングをサポートするために必要なインターフェイスを実装する方法について説明します。
INotifyPropertyChangedの実装
ビューモデルまたはモデルのクラスに
INotifyPropertyChanged
インターフェイスを実装すると、値が変更されたときにビューの関連コントロールに通知できます。 次の例に示すように、このインターフェイスの実装は比較的単純です(
Basic MVVM QuickStartの Questionnaire
クラスを参照)。
public class Questionnaire : INotifyPropertyChanged { private string favoriteColor; public event PropertyChangedEventHandler PropertyChanged; ... public string FavoriteColor { get { return this.favoriteColor; } set { if (value != this.favoriteColor) { this.favoriteColor = value; if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs("FavoriteColor")); } } } } }
ビューモデルの多くのクラスでの
INotifyPropertyChanged
インターフェイスの実装は、プロパティ名を定義する必要があるために繰り返され、エラーが発生しやすくなります。 Prismライブラリは、以下に示すように、
INotifyPropertyChanged
セーフな方法で
INotifyPropertyChanged
インターフェイスを実装するビューモデルクラスを継承できる便利な基本クラスを提供します。
public class NotificationObject : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; ... protected void RaisePropertyChanged<T>( Expression<Func<T>> propertyExpression) {...} protected virtual void RaisePropertyChanged(string propertyName) {...} }
継承されたビューモデルクラスは、以下に示すように、特定のプロパティ名で
RaisePropertyChanged
を呼び出すか、プロパティにアクセスするラムダ式を使用して、プロパティ変更イベントを生成できます。
public string CurrentState { get { return this.currentState; } set { if (this.currentState != value) { this.currentState = value; this.RaisePropertyChanged(() => this.CurrentState); } } }
ご注意
この方法でラムダ式を使用すると、クエリごとにラムダ式を評価する必要があるため、パフォーマンスがわずかに低下します。 , , . , , . , , .
ご注意
Resharper , .
多くの場合、モデルまたはビューモデルには、モデルまたはビューモデルの他のプロパティに応じて値が計算されるプロパティが含まれます。プロパティ変更イベントを生成するときは、依存プロパティの通知イベントも必ず生成してください。あなたが最初の2つのフィールドの合計を表すフィールドPrice1、Price2とSumPriceを持っている場合には、フィールドのセッターPrice1
とは、Price2
上記のすべてのメソッドと呼ばれるべきですRaisePropertyChanged(“SumPrice”)
。INotifyCollectionChangedの実装
ビューモデルのクラスまたはモデルは、要素のコレクションにすることも、コレクションを返す1つ以上のプロパティを持つこともできます。それ以外の場合は、おそらく、またはItemsControl
などの相続人のいずれかでコレクションを表示することができます。これらのコントロールは、プロパティを介してコレクションを返すコレクションまたはプロパティを提供するビューモデルに関連付けることができます。ListBox
DataGrid
ItemSource
<DataGrid ItemsSource="{Binding Path=LineItems}" />
オブジェクトのコレクションへの変更に関する通知要求を適切にサポートするには、ビューモデルのクラスまたはコレクションであるモデルは、インターフェイスをINotifyCollectionChanged
(インターフェイスに加えてINotifyPropertyChanged
)実装する必要があります。ビューモデルまたはモデルのクラスが、コレクションへの参照を返すプロパティを定義する場合、返されるコレクションクラスはinterfaceを実装する必要がありますINotifyCollectionChanged
。ただし、INotifyCollectionChanged
コレクション内でアイテムが追加、削除、移動、または変更されたときに通知を送信する必要があるため、インターフェイスの実装はかなり複雑です。多くの場合、インターフェイスを直接実装する代わりに、直接使用するか、既に実装されているコレクションクラスから継承する方が簡単です。クラスObservableCollection<T>
このインターフェイスを実装し、通常は基本クラスとして、または要素のコレクションを表すプロパティで使用されます。ビューにデータをバインドするコレクションを作成する必要があり、アイテムのユーザー選択を追跡したり、コレクション内のアイテムのフィルタリング、並べ替え、グループ化をサポートする必要がない場合は、インスタンスへの参照を返すプロパティをビューモデルに定義するだけObservableCollection<T>
です。 public class OrderViewModel : INotifyPropertyChanged { public OrderViewModel(IOrderService orderService) { this.LineItems = new ObservableCollection<OrderLineItem>( orderService.GetLineItemList()); } public ObservableCollection<OrderLineItem> LineItems { get; private set; } }
コレクションクラスへの参照を(たとえば、実装していない別のコンポーネントまたはサービスからINotifyCollectionChanged
)ObservableCollection<T>
取得するIEnumerable<T>
場合、どちらかをパラメーターとして取るコンストラクターの1つを使用して、このコレクションをインスタンスでラップできますList<T>
。ICollectionViewの実装(コレクションビュー)
前のコード例は、ビューの関連コントロールを介して表示できる要素のコレクションを返すビューモデルの単純なプロパティを実装する方法を示しています。ObservableCollection<T>
インターフェースを実装しているためINotifyCollectionChanged
、ビューのコントロールは要素が追加または削除されると自動的に更新されます。多くの場合、ビューでの要素のコレクションの表示方法をより正確に制御するか、ビューのモデル内で表示されている要素のコレクションとのユーザーの対話を追跡する必要があります。たとえば、プレゼンテーションモデルに実装されたプレゼンテーションロジックに従って要素のコレクションをフィルター処理または並べ替えたり、ビューで現在選択されている要素を追跡して、プレゼンテーションモデルに実装されたコマンドが選択された要素のみに影響を与えるようにすることができます。WPFおよびSilverlightは、インターフェイスを実装するさまざまなクラスを提供することにより、このようなシナリオをサポートします。ICollectionView
。このインターフェイスは、コレクションのフィルター処理、並べ替え、またはグループ化を可能にするプロパティとメソッドを提供し、現在選択されているアイテムを追跡または変更することもできます。 SilverlightとWPFはどちらもこのインターフェイスの実装を提供し、Silverlightはクラスを提供し、PagedCollectionView
WPF はクラスを提供しますListCollectionView
。コレクションビュークラスは、選択されたアイテムを自動的に追跡し、並べ替え、フィルター、およびアラートできるように、アイテムの基本コレクションをラップすることによって機能します。これらのクラスのインスタンスは、クラスを使用して、プログラムまたはXAMLで宣言的に作成できますCollectionViewSource
。ご注意
WPF CollectionView , . Silverlight , ICollectionViewFactory
.
ビューモデルは、コレクションビュークラスを使用して、ベースコレクションの重要な状態情報を追跡し、ビューのUIとモデルの基になるデータとの間の職務の分離をサポートできます。実際、これらCollectionViews
はコレクションをサポートするために特別に設計されたプレゼンテーションモデルです。したがって、ビューモデル内からコレクション内のアイテムの選択をフィルター処理、並べ替え、グループ化、または追跡する必要がある場合、ビューモデルは、ビューに提供されるコレクションごとにコレクションビュークラスのインスタンスを作成する必要があります。その後、次のような選択イベントにサブスクライブできます。CurrentChanged
、またはビューモデル内のコレクションビュークラスメソッドを使用して、フィルタリング、並べ替え、またはグループ化を管理します。ビューモデルは、参照を返す読み取り専用プロパティを実装ICollectionView
して、ビュー内のコントロールがコレクションビューにデータをバインドし、それと対話できるようにする必要があります。基本クラスからのすべてのWPFおよびSilverlightコントロールは、ItemsControl
自動的にクラスと対話できますICollectionView
。次の例では、PagedCollectionView
Silverlightを使用して、現在選択されているクライアントを追跡します。 public class MyViewModel : INotifyPropertyChanged { public ICollectionView Customers { get; private set; } public MyViewModel(ObservableCollection<Customer> customers) { Customers = new PagedCollectionView(customers); Customers.CurrentChanged += new EventHandler(SelectedItemChanged); } private void SelectedItemChanged(object sender, EventArgs e) { Customer current = Customers.CurrentItem as Customer; ... } }
ビューでは、次のItemsControl
ようにListBox
、property などを使用して、などCustomers
のビューモデルのプロパティに関連付けることができItemsSource
ます。 <ListBox ItemsSource="{Binding Path=Customers}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding Path=Name}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
ユーザーがUIでクライアントを選択すると、プレゼンテーションモデルに通知され、選択したクライアントのみに関係するコマンドを実行できます。次の例に示すように、ビューモデルは、コレクションビューオブジェクトのメソッドを呼び出すことにより、プログラムでUIの現在の選択を変更することもできます。 Customers.MoveCurrentToNext();
コレクションビューで選択したアイテムが変更されると、UIが自動的に更新され、選択したアイテムの状態が視覚的に示されます。実装はWPFに似ていますPagedCollectionView
が、前の例では、通常、クラスListCollectionView
、またはに置き換えられますが、BindingListCollectionView
以下に示します。 Customers = new ListCollectionView(_model); Customers.CurrentChanged += new EventHandler(SelectedItemChanged);
チーム
ビューで表示または編集されるデータへのアクセスを提供することに加えて、ビューモデルは、ユーザーが実行できる1つ以上のアクションまたは操作を定義する可能性があります。 WPFおよびSilverlightでは、ユーザーがUIを介して実行できるアクションまたは操作は通常、コマンドとして定義されます。コマンドは、UIのコントロールに簡単に結び付けることができるアクションまたは操作を表示する便利な方法を提供します。これらは、必要なアクションを実装するコードをカプセル化し、視覚的表現から分離するのに役立ちます。コマンドは、さまざまな方法でユーザーが視覚的に提示および呼び出すことができます。ほとんどの場合、マウスクリックによってトリガーされますが、キーストローク、タッチジェスチャ、またはその他の入力イベントによってトリガーすることもできます。ビュー内のコントロールはビューモデルのコマンドに関連付けられているため、ユーザーはコントロールで定義された入力イベントを使用してそれらを呼び出すことができます。ビュー内のUIコントロールとチームの間の相互作用は双方向になります。この場合、ユーザーがUIを操作することでコマンドがトリガーされ、基本的なコマンドがオンまたはオフになると、コントロールが自動的にロック解除またはロックされる場合があります。ビューモデルはコマンドを次のように実装できますCommand Method、またはCommand Object(インターフェイスを実装するオブジェクトICommand
)として。いずれの場合でも、ビューとコードビハインドの複雑なイベント処理コードを必要とせずに、ビューとチームの相互作用を宣言的に定義できます。たとえば、WPFおよびSilverlightの特定のコントロールはコマンドをサポートし、ビューモデルのCommand
typeプロパティICommand
に関連付けられるプロパティを提供します。その他の場合、CommandBehavior
コントロールをプレゼンテーションモデルのコマンドメソッドまたはコマンドオブジェクトに関連付けるために使用できます。ご注意
ビヘイビアは、対話ロジックとビヘイビアをカプセル化するために使用できる強力で柔軟な拡張性メカニズムであり、ビュー内のコントロールに宣言的に関連付けることができます。CommandBehavior
コマンドオブジェクトまたはメソッドを、チームと対話するように特別に設計されていないコントロールに関連付けるために使用できます。
次のセクションでは、メソッドまたはコマンドオブジェクトとしてビューにコマンドを実装する方法、およびそれらをビュー内のコントロールに関連付ける方法について説明します。コマンドオブジェクトの実装
コマンドオブジェクトは、インターフェイスを実装するオブジェクトですICommand
。このインターフェイスはExecute
、必要なアクションをカプセル化するメソッドCanExecute
と、特定の時間にコマンドを呼び出すことができるかどうかを示すメソッドを定義します。これらのメソッドは両方とも、コマンドへのパラメーターとして単一の引数を受け入れます。ロジックをコマンドオブジェクトにカプセル化するということは、テストと保守が簡単になることを意味します。インターフェイスの実装はICommand
比較的簡単です。ただし、アプリケーションで簡単に使用できるこのインターフェイスの実装は多数あります。たとえばActionCommand
、Expression Blend SDKのクラス、またはDelegateCommand
Prismが提供するクラスを使用できます。クラスDelegateCommand
ビューモデルクラス内に実装されたメソッドをそれぞれ参照する2つのデリゲートをカプセル化します。これらのデリゲートを呼び出すことにより、DelegateCommandBase
メソッドExecute
とCanExecute
インターフェイスを実装するクラスから継承しますICommand
。クラスコンストラクターのビューモデルメソッドでデリゲートを定義しますDelegateCommand
。これは次のようになります。 public class DelegateCommand<T> : DelegateCommandBase { public DelegateCommand(Action<T> executeMethod, Func<T,bool> canExecuteMethod) :base((o) => executeMethod((T)o), (o) => canExecuteMethod((T)o)) { ... } }
たとえば、次のコードは、プレゼンテーションモデルメソッドおよびにデリゲートを作成することによりDelegateCommand
、コマンドを表すインスタンスがどのようにSubmit
作成されるかを示しています。コマンドは、へのリンクを返す読み取り専用プロパティを介してビューに渡されます。OnSubmit
CanSubmit
ICommand
public class QuestionnaireViewModel { public QuestionnaireViewModel() { this.SubmitCommand = new DelegateCommand<object>( this.OnSubmit, this.CanSubmit); } public ICommand SubmitCommand { get; private set; } private void OnSubmit(object arg) {...} private bool CanSubmit(object arg) { return true; } }
Execute
オブジェクトDelegateCommand
でメソッドが呼び出されると、呼び出しは、コンストラクターで定義したデリゲートを介して、ビューモデルクラスのメソッドにリダイレクトされます。同様に、メソッドCanExecute
が呼び出されると、ビューモデルクラスの対応するメソッドが呼び出されます。CanExecute
コンストラクター内のメソッドへのデリゲートはオプションです。デリゲートが定義されていない場合は、DelegateCommand
必ず戻りますtrue
しCanExecute
。クラスDelegateCommand
はジェネリック型です。 typeパラメーターは、渡されるコマンドパラメーターのタイプExecute
とmethodsを決定しますCanExecute
。前の例では、コマンドパラメーターのタイプはobject
です。クラスのユニバーサルバージョンではありませんDelegateCommand
Prismは、コマンドパラメーターが不要な場合に使用するためにも提供されています。ビューモデルは、オブジェクトのCanExecute
メソッドRaiseCanExecuteChanged
を呼び出すことにより、コマンドメソッドの状態の変化を示すことができますDelegateCommand
。これにより、イベントがトリガーされCanExecuteChanged
ます。チームに関連付けられているUIのコントロールは、状態を更新して、関連付けられたチームの可用性を反映します。他のインターフェース実装は利用可能ですICommand
。クラスActionCommand
SDKのExpression Blendの中には、プリズムのクラスに似ているDelegateCommand
、先に説明したが、それは、単一のデリゲートメソッドをサポートしていますExecute
。 Prismは、実行のためにCompositeCommand
グループ化できるクラスも提供しますDelegateCommands
。クラスの使用の詳細についてはCompositeCommand
、第6章「高度なMVVMシナリオ」の「複合コマンド」を参照してください。ビューからコマンドオブジェクトを呼び出す
ビュー内のコントロールをビューモデルによって提供されるコマンドオブジェクトに関連付けるには、多くの方法があります。要素WPFとSilverlight特にから継承された4制御、ButtonBase
などButton
、RadioButton
、Hyperlink
、またはから継承はMenuItem
、容易性を介してコマンドオブジェクトに接続することができますCommand
。WPFはへのバインドもサポートしICommand
ていKeyGesture
ます。 <Button Command="{Binding Path=SubmitCommand}" CommandParameter="SubmitOrder"/>
さらに、プロパティを使用してコマンドパラメータを設定できますCommandParameter
。期待されるパラメーターのタイプは、ターゲットメソッドExecute
およびで決定されますCanExecute
。ユーザーがこのコントロールを操作すると、コントロールは自動的にターゲットコマンドを呼び出し、コマンドパラメーターがあれば、Execute
コマンドメソッドにパラメーターとして渡されます。前の例では、ボタンをクリックすると自動的に呼び出されSubmitCommand
ます。さらに、ハンドラーが定義されているCanExecute
場合、ボタンがCanExecute
戻るfalse
と自動的に無効になり、が有効になるとボタンが有効になりますtrue
。別のアプローチは、Expression Blendの相互作用トリガーと動作を使用することInvokeCommandAction
です。 <Button Content="Submit" IsEnabled="{Binding CanSubmit}"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:InvokeCommandAction Command="{Binding SubmitCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> </Button>
このアプローチは、相互作用トリガーをアタッチできるコントロールに使用できます。これは、子孫ButtonBase
ではないコントロールにコマンドを添付する場合、またはクリックイベント以外のイベントでコマンドを呼び出す場合に特に便利です。コマンドのパラメーターを渡す必要がある場合は、プロパティを使用できることを思い出してくださいCommandParameter
。コマンドに直接関連付けることができるコントロールとは異なり、コマンドInvokeCommandAction
の値に基づいてコントロールを自動的に有効または無効にすることはありませんCanExecute
。この動作を実装するには、プロパティをバインドする必要がありますIsEnabled
上記のように、ビューモデルの適切なプロパティにコントロールするか、コマンドの可用性に応じて、コントロールを無効にする独自の特別な動作を記述します。ご注意
WPFおよびSilverlight 4のコマンドサポートコントロールを使用すると、コントロールを宣言的にコマンドにバインドできます。これらのコントロールは、ユーザーが操作すると指定されたコマンドを呼び出します。たとえば、コントロールのButton
場合、ユーザーがボタンをクリックするとコマンドが呼び出されます。コマンドに関連付けられたこのイベントは修正されており、変更できません。
また、ビヘイビアを使用すると、コントロールを宣言的な方法でコマンドオブジェクトに接続できます。ただし、ビヘイビアーはコントロールによって生成されたさまざまなイベントに関連付けることができ、指定された条件が満たされたときにプレゼンテーションモデル内の関連付けられたコマンドオブジェクトまたはコマンドメソッドを呼び出すために使用できます。つまり、ビヘイビアは、サポートされているコマンドコントロールと同じシナリオの多くを実装でき、柔軟性と制御の度合いを高めることができます。チームがサポートするコントロールを使用するタイミング、ビヘイビアを使用するタイミング、および使用するビヘイビアの種類を選択する必要があります。ビューのコントロールをビューモデルの機能とリンクするため、または一貫性のために単一のメカニズムを使用する場合は、コマンドをサポートするコントロールであっても、動作の使用を検討してください。コマンドをサポートするコントロールのみを使用する必要があり、標準のコマンド呼び出しイベントに満足している場合は、これを行う必要さえないかもしれません。同様に、開発者またはUI開発者がExpression Blendを使用しない場合、Expression Blendの動作を使用するために必要な追加の構文のため、コマンド互換のコントロール(またはカスタムアタッチされた動作)のみを選択できます。ビューからコマンドメソッドを呼び出す
オブジェクトとしてコマンドを実装する別のアプローチICommand
は、単にビューモデルのメソッドとしてコマンドを実装し、ビヘイビアを使用してこれらのメソッドをビューから直接呼び出すことです。これは、前のセクションで示した動作からコマンドを呼び出すのと同様の方法で実現できます。ただし、を使用する代わりにInvokeCommandAction
が使用されCallMethodAction
ます。次の例ではSubmit
、ベースビューモデルのメソッド(パラメーターなし)を呼び出します。 <Button Content="Submit" IsEnabled="{Binding CanSubmit}"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:CallMethodAction TargetObject="{Binding}" Method="Submit"/> </i:EventTrigger> </i:Interaction.Triggers> </Button>
TargetObject
式を使用するときに、基になるデータコンテキスト(ビューモデル)にバインドします{Binding}
。パラメーターMethod
は、呼び出すメソッドを定義します。ご注意
CallMethodAction
. , , InvokeCommandAction
, CallMethodAction
, .
プレゼンテーションモデルまたはモデルは、多くの場合、データを検証し、プレゼンテーションのデータの正確性のエラーを通知して、ユーザーが修正できるようにする必要があります。SilverlightとWPFは、ビュー内のコントロールに関連付けられた個々のプロパティが変更されたときに発生するデータ検証エラーの管理をサポートします。コントロールに関連付けられている個々のプロパティの場合、ビューモデルまたはモデルはプロパティのsetメソッド内でデータ検証エラーを通知し、着信する不正な値を拒否して例外をスローします。ValidatesOnExceptions
データバインディングオブジェクトのプロパティが等しい場合true
、WPFおよびSilverlightのデータバインディングメカニズムは例外を処理し、検証エラーの存在を視覚的に示します。ただし、プロパティによる例外のスローは、可能な場合は避ける必要があります。別のアプローチは、ビューモデルまたはモデルのクラスのIDataErrorInfo
いずれかでインターフェイスを実装することINotifyDataErrorInfo
です。これらのインターフェイスにより、ビューモデルまたはモデルは1つ以上のプロパティの値を検証し、エラーメッセージをビューに返して、ユーザーに通知することができます。IDataErrorInfoの実装
インターフェイスIDataErrorInfo
は、データの検証とエラーメッセージの基本的なサポートを提供します。これは、2つの読み取り専用プロパティを定義しますError
。インデクサーのプロパティ(インデクサーのパラメーターとしてのプロパティの名前)とproperty です。両方のプロパティは文字列値を返します。インデクサープロパティにより、ビューモデルまたはモデルクラスは、名前付きプロパティに固有のエラーメッセージを提供できます。空の文字列またはnullの戻り値は、変更されたプロパティ値が有効であることをビューに示します。 Errorプロパティを使用すると、ビューモデルまたはモデルクラスでオブジェクト全体のエラーメッセージを提供できます。現在、このプロパティはSilverlightまたはWPFデータバインディングエンジンによって呼び出されないことに注意してください。インデクサープロパティIDataErrorInfo
データ関連のプロパティが表示されたとき、およびその後変更されたときに呼び出されます。インデクサーのプロパティは、変化するすべてのプロパティに対して呼び出されるため、データ検証が可能な限り高速で効率的であることを保証するために、すべてを行う必要があります。ビュー内のコントロールをプロパティにバインドする場合、インターフェイスを介してコントロールをテストし、データバインドのIDataErrorInfo
プロパティをValidatesOnDataErrors
に設定しますtrue
。これにより、データバインディングエンジンが関連するプロパティからエラー情報を要求するようになります。 <TextBox Text="{Binding Path=CurrentEmployee.Name, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True }"/>
INotifyDataErrorInfoの実装
インターフェースはINotifyDataErrorInfo
、インターフェースよりも柔軟ですIDataErrorInfo
。プロパティの複数のエラー、データの非同期検証、およびオブジェクトのエラー状態の変更をビューに通知する機能をサポートしています。ただし、INotifyDataErrorInfo
現在はSilverlight 4でのみサポートされており、WPF 4では使用できません。ご注意
このインターフェイスは、.NET Framework 4.5のWPFでもサポートされるようになりました。
インターフェイスINotifyDataErrorInfo
はHasErrors
、ビューモデルがプロパティにエラー(または複数のエラー)が存在するかどうかを示すことを可能にするプロパティと、ビューモデルがGetErrors
特定のプロパティのエラーメッセージのリストを返すことを可能にするメソッドを定義します。インターフェースINotifyDataErrorInfo
はイベントも定義しますErrorsChanged
。非同期検証スクリプトをサポートし、ビューモデルまたはビューがイベントを介して特定のプロパティのエラー状態の変更を通知できるようにしますErrorsChanged
。プロパティ値は、データバインディングだけでなく、たとえば、Webサービスリクエストやバックグラウンド計算の結果として、さまざまな方法で変更できます。イベントErrorsChanged
データ検証エラーが識別されるとすぐに、ビューモデルがビューにエラーを報告できるようにします。サポートのためにINotifyDataErrorInfo
、各プロパティのエラーのリストを保持する必要があります。Model-View-ViewModel参照実装(MVVM RI)ErrorsContainer
は、オブジェクトのすべての検証エラーを追跡するコレクションクラスを使用してこれを行う1つの方法を示しています。また、エラーリストが変更された場合に通知イベントを生成します。次の例は、クラスを使用した(DomainObject
モデルのルートオブジェクト)と実装INotifyDataErrorInfo
を示していErrorsContainer
ます。 public abstract class DomainObject : INotifyPropertyChanged, INotifyDataErrorInfo { private ErrorsContainer<ValidationResult> errorsContainer = new ErrorsContainer<ValidationResult>( pn => this.RaiseErrorsChanged(pn)); public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; public bool HasErrors { get { return this.ErrorsContainer.HasErrors; } } public IEnumerable GetErrors(string propertyName) { return this.errorsContainer.GetErrors(propertyName); } protected void RaiseErrorsChanged(string propertyName) { var handler = this.ErrorsChanged; if (handler != null) { handler(this, new DataErrorsChangedEventArgs(propertyName)); } } ... }
Silverlightでは、ビューモデルのプロパティに関連付けられたコントロールデータは、イベントに自動的にサブスクライブしINotifyDataErrorInfo
、プロパティにエラーが含まれている場合、コントロールにエラー情報を表示します。作成と集約
MVVMパターンは、UIをプレゼンテーション、ビジネスロジック、およびデータから分離するのに役立つため、適切なコードを適切なクラスに配置することは、このパターンを効果的に使用するための重要な最初のステップです。データとコマンドをバインドすることにより、プレゼンテーションモデルのクラスとプレゼンテーションの間の相互作用を管理することも、考慮する重要な側面です。次のセクションでは、実行時にビュー、ビューモデル、モデルクラスがどのように作成され、相互作用するかを示します。ご注意
, . Managed Extensibility Framework (MEF) Unity Application Block (Unity) , , . , . 6, « MVVM».
通常、ビューとそのプレゼンテーションモデルの間には直接的な関係があります。プレゼンテーションモデルとプレゼンテーションは、プレゼンテーションデータのコンテキストプロパティによって疎結合されています。これにより、ビューの視覚的な要素と動作を、ビューモデルのプロパティ、コマンド、およびメソッドに関連付けることができます。ビューのモデルクラスの作成と、DataContext
実行時のプロパティを介したビューとそれらの関連付けの作成を制御する方法を決定する必要があります。また、プレゼンテーションとプレゼンテーションモデルを作成して接続するときは、弱い結合が残るように注意する必要があります。前のセクションで述べたように、プレゼンテーションモデルはビューの特定の実装に依存するべきではありません。同様に、プレゼンテーションは、プレゼンテーションモデルの特定の実装に依存すべきではありません。ご注意
ただし、ビューは、データバインディングにより、ビューモデルの特定のプロパティ、コマンド、およびメソッドに暗黙的に依存することに注意してください。ビューモデルが必要なプロパティ、コマンド、またはメソッドを実装していない場合、実行時に例外が生成され、デバッグ中にVisual Studioの出力ウィンドウに表示されます。
ビューとプレゼンテーションモデルを実行時に作成およびリンクする方法は多数あります。アプリケーションに最適な方法を選択するかどうかは、ビューまたはプレゼンテーションモデルを最初に作成するかどうか、およびプログラムで作成するか宣言的に作成するかによって大きく異なります。次のセクションでは、実行時にプレゼンテーションクラスとプレゼンテーションモデルを作成し、相互にリンクする一般的な方法について説明します。XAMLを介してビューモデルを作成する
おそらく、提示する最も簡単なアプローチは、XAMLで対応する表現モデルを宣言的に作成することです。ビューが作成されると、対応するビューモデルオブジェクトも作成されます。ビューモデルがビューデータのコンテキストとして設定されるようにXAMLで指定することもできます。XAMLベースのアプローチはQuestionnaireView.xaml
、Basic MVVM QuickStartのファイルに示されています。その例では、次のようにインスタンスQuestionnaireViewModel
がXAML QuestionnaireView
で定義されています。 <UserControl.DataContext> <my:QuestionnaireViewModel/> </UserControl.DataContext>
ときにQuestionnaireView
作成され、コピーがQuestionnaireViewModel
自動的に作成され、データコンテキスト表現としてインストールされます。このアプローチでは、ビューモデルにデフォルトコンストラクター(パラメーターなし)が必要です。ビューによるプレゼンテーションモデルの宣言的な作成と割り当てには、シンプルであり、Microsoft Expression BlendやMicrosoft Visual Studioなどのデザイン時ツールでうまく機能するという利点があります。このアプローチの欠点は、ビューが対応するプレゼンテーションモデルを認識していることです。プログラムでプレゼンテーションモデルを作成する
ビューは、コンストラクターでプログラムによってビューモデルの対応するインスタンスを作成します。次の例に示すように、データコンテキストとして設定できます。 public QuestionnaireView() { InitializeComponent(); this.DataContext = new QuestionnaireViewModel(); }
コードビハインドビュー内でビューモデルをプログラムで作成して割り当てることには、この方法が簡単で、Expression BlendやVisual Studioなどのデザイン時ツールでうまく機能するという利点があります。このアプローチの欠点は、ビューがビューモデルの適切なタイプを知る必要があり、分離コードビューのコードを必要とすることです。UnityやMEFなどの依存性注入コンテナーを使用すると、ビューモデルとビューの間に弱いリンクを提供できます。詳細については、第3章「コンポーネント間の依存関係の管理」を参照してください。データテンプレートとして定義されたビューの作成
ビューはデータテンプレートとして定義でき、ビューモデルのタイプに関連付けられます。データテンプレートは、ビューモデルを表示するコントロール内のリソースまたは埋め込みとして定義できます。コントロールの「コンテンツ」はプレゼンテーションモデルのインスタンスであり、データテンプレートを使用して視覚化します。 WPFおよびSilverlightは、データテンプレートを自動的に作成し、そのデータコンテキストを実行時にビューモデルのインスタンスに設定します。このメソッドは、リプレゼンテーションモデルが最初に作成され、次にリプレゼンテーションモデルが作成される状況の例です。データテンプレートは柔軟で軽量です。 UI開発者はこれらを使用して、複雑なコードなしでプレゼンテーションモデルの視覚的表現を簡単に定義できます。データテンプレートは、UI(分離コード)ロジックを必要としないビューに限定されます。データテンプレートの視覚的なデザインと編集には、Microsoft Expression Blendを使用できます。次の例はItemsControl
、顧客リストに関連付けられているものを示しています。基本コレクションの各コンシューマオブジェクトは、プレゼンテーションモデルのインスタンスです。クライアントのプレゼンテーションは、組み込みのデータテンプレートによって決定されます。次の例では、各コンシューマプレゼンテーションモデルのプレゼンテーションStackPanel
はName
、プレゼンテーションモデルのプロパティに関連付けられたラベルとテキストボックスで構成されています。 <ItemsControl ItemsSource="{Binding Customers}"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock VerticalAlignment="Center" Text="Customer Name: " /> <TextBox Text="{Binding Name}" /> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
データテンプレートをリソースとして指定することもできます。次の例は、リソースとして定義され、マークアップ拡張機能を介してコントロールに適用されるデータテンプレートを示していますStaticResource
。 <UserControl ...> <UserControl.Resources> <DataTemplate x:Key="CustomerViewTemplate"> <local:CustomerContactView /> </DataTemplate> </UserControl.Resources> <Grid> <ContentControl Content="{Binding Customer}" ContentTemplate="{StaticResource CustomerViewTemplate}" /> </Grid> </Window>
ここで、データテンプレートは特定のタイプのビューをラップするため、ビューで分離コードの動作を定義できます。したがって、テンプレート化されたデータエンジンを使用して、プレゼンテーションとプレゼンテーションモデルの関係を表面的に提供できます。前の例ではresources UserControl
にテンプレートを示していますが、多くの場合、アプリケーションリソースに配置したりResourceDictionary
、再利用したりします。データテンプレートを使用した例では、ビューが作成され、QuickStart MVVM ファイルでビューモデルに関連付けられていることがわかりますQuestionnaireView.xaml
。重要な決定
アプリケーションの作成時にMVVMパターンを使用することにした場合、後で変更するのが難しい特定の設計上の決定を行う必要があります。通常、これらはアプリケーション全体のソリューションであり、アプリケーション全体で一貫して使用することで、開発者とデザイナーの生産性が向上します。以下は、MVVMパターンを実装する際の最も重要な決定事項です。- , . , , , Unity MEF. , . , . , «Advanced Construction and Wire-Up» «Advanced MVVM Scenarios» 6, «Advanced MVVM Scenarios.»
- , . . /
Command
ButtonBase
. , . , «» . - , .
IDataErrorInfo
, INotifyDataErrorInfo
. , , , , . , « » . - , Microsoft Expression Blend . Expression Blend UI , , , . , , Microsoft Expression Blend, ,
d:DataContext
d:DesignSource
. , «Guidelines for Creating Designer Friendly Views» 7 «Composing the User Interface».
WPFでデータバインディングの詳細については、MSDNに«データバインディング»参照:http://msdn.microsoft.com/en-us/library/ms750612.aspx。:Silverlightでのデータバインディングについては、MSDNの«データバインディング»チェックhttp://msdn.microsoft.com/en-us/library/cc278072(VS.95).aspx。:WPFでのコレクションへのリンクの詳細については、MSDNに«概要データバインディング»で«コレクションへの結合»参照http://msdn.microsoft.com/en-us/library/ms752347.aspx。:Silverlightでのコレクションへのリンクの詳細については、MSDNに«データバインディング»で«コレクションへの結合»参照http://msdn.microsoft.com/en-us/library/cc278072(VS.95).aspx。プレゼンテーションモデルの詳細については、Martin FowlerのWebサイトの「プレゼンテーションモデル」を参照してください。http ://www.martinfowler.com/eaaDev/PresentationModel.htmlデータテンプレートの詳細については、MSDNの「データテンプレートの概要」を参照してください。 :http ://msdn.microsoft.com/en-us/library/ms742521.aspx MEFの詳細については、MSDNの「Managed Extensibility Framework Overview」を参照してください :http : //msdn.microsoft.com/en-us /library/dd460648.aspxユニティの詳細については、MSDNの«ユニティアプリケーションブロック»参照:http://www.msdn.com/unityの詳細については、DelegateCommand
とCompositeCommand
一部9を参照してください"疎結合コンポーネント間の通信。」