※サンプルコードのダウンロードは、原文リンクから行ってください。
パターンと実践 ディベロパー・センター
MVVM QuickStart Using the Prism Library 5.0 for WPF (原文)
Microsoft Prism Library 5.0 for WPFの開発者のガイドから:
Model-View-ViewModel(MVVM)クイックスタートは、状態とロジックをどのように分離するかを説明するサンプルコードを提供します。 それは、Prismライブラリを使用して、ViewModelという名前の分離したクラスに、Viewをサポートします。 Viewをサポートするために必要な状態やデータを提供するために、View Modelは、アプリケーション・データ・モデルの上で位置します。 アプリケーションの完全な複雑さを知っている必要から、Viewを隔離します。また、View ModelはViewのための相互作用ロジックをカプセル化します。 それは、View要素自体には、直接、依存していません。 このクイックスタートでは、MVVMパターンを実装することに関するチュートリアルを提供します。
MVVMアプリケーションで、ViewとView Modelを設計する一般的な方法は、どのViewが画面上で見えるかという、最初のスケッチやストーリーボードです。 続いて、あなたは、そのデータが、どのようにViewModelになるか気にすることなく、View ModelのどんなプロパティをViewで公開し、 サポートする必要があるか、識別するために、その画面を分析します。後で、あなたは、どんなView Modelを、Viewに公開する必要があるか定義し、 それを実装します。あなたは、続いて、どのように、データをView Modelに取得するかに、飛び込むことができます。多くの場合、 これは、ViewModelが、データを取り出すために、サービスを呼び出すことを含んでいます。 そして、ときどき、データは、アプリケーション・コントロールのような、いくつかの他のコードから、ViewModelに、押しこむことができます。
このクイックスタートは、あなたを、次の手順に案内します。:
- どんな状態が、それをサポートするために、ViewModelに必要か決定するためにViewを分析します。
- Viewをサポートするために、View Modelクラスと最小の実装を定義します。
- Viewに、ViewがView Modelに添付しているView Modelのプロパティを示す結合を定義します。
- ViewをView Modelに添付する
実際の使い方
Business Scenario
基本的なMVVMアプリケーション・クイックスタートのメイン・ウィンドウは、調査アプリケーションのサブセットを表示します。 このウィンドウの中で、異なる種類の質問による、無駄な調査が示されます。; そして、アンケ-卜用紙を提出するボタンがあります。次に示す図は、クイックスタートのメイン・ウィンドウを示しています。
クイックスタートを構築して、そして、実行する
Building and Running the QuickStart
このクイックスタートは、Microsoft Visual Studio 2012以降と.NET Framework 4.5.1を必要とします。
MVVMのクイックスタートを構築して、実行するには、
- Visual Studioで、ソリューション・ファイルQuickstarts\BasicMVVMQuickstart_Desktop\BasicMVVMQuickstart_Desktop.slnを開きます。
- Buildメニューで、ソリューションのリビルドをクリックします。
- QuickStartを実行するために、F5を押してください。
実装の詳細
Implementation Details
クイックスタートは、基礎アプリケーションで、MVVMパターンを実装するために、鍵となる要素と考慮すべき問題を強調しています。
どんなプロパティが、ViewModel上で必要か分析する
Analyzing What Properties Are Needed on the View Model
デザイナー内で、Views\MainWindow Viewを開きます。色選択のリストが、動的に埋め込まれます。 View Modelを定義するために、Viewを分析するとき、あなたは、あなたが必要な、それぞれデータの項目と動作を別々に識別することを望みます。 この場合、質問が固定されて、動的に動かさない場合は、あなたは、あなたのViewモデルから、次に示す公開されるプロパティが必要となります。:
- Name: string
- Age: int
- Quest: string
- FavoriteColor: string
- Submit: Command
- Reset: Command
なぜなら、最初の4つのプロパティは、アンケ-卜用紙と関連づけられています。 アンケ-卜用紙クラスは、それらを格納するために作成されます。アンケ-卜用紙クラスは、アプリケーションのModelです。 そして、View Modelは、それらをサポートするために、Questionnaire型のプロパティを一つだけ公開します。
ボタンのようなものでさえ、View Modelからのサポートを必要とする何かを表していることに注意します。 あなたは、このクイックスタートで示すように、あるいは、あなたは、メソッドを公開することのどちらかで、コマンドを公開することができます。 前者では、あなたは、ICommandインターフェイスを実装するオブジェクトで、View Modelから公開するプロパティを必要とするでしょう。; 後者で、あなたは、メソッドを対象とすることができる動作を必要とします。
備考
ボタンをクリックするために、あなたは、コマンドや動作の選択を持っています。 詳細については、 有効なコマンドのコントロール対ビヘイビア(原文)については、高等なMVVMの筋書きを参照してください。 このトピックでは、あなたは、コマンドを使用するでしょう。それを行うには、あなたは、コマンドの実装を必要とします。 それは、.NET Frameworkで、Viewモデルの互換性を持つフォ-ム内に存在しません。 Prismは、コマンドで、Viewを、View Modelにフックすることのための、完全なDelegateCommandクラスを提供します。
私たちが、親-子Viewモデル構成を説明したいため、アプリケーションUIは、2つのViewで構成されます。: MainWindowは、アンケ-卜用紙の質問が含まれるQuestionnaireViewに、ResetとSubmitボタンと2つ目のViewのインスタンスが含まれています。
次のコードで確かめられるように、QuestionnaireViewは、直接、XAMLのコードでインスタンスを生成されます。
XAML
<Window x:Class="BasicMVVMQuickstart_Desktop.Views.MainWindow" ...>
<Grid x:Name="LayoutRoot"
Background="{StaticResource MainBackground}">
<Grid MinWidth="300" MaxWidth="800">
...
<views:QuestionnaireView Grid.Row="1"
DataContext="{Binding QuestionnaireViewModel}"
Height="246" VerticalAlignment="Top">
</views:QuestionnaireView>
...
</Grid>
</Grid>
</Window>
子のQuestionnaireViewのViewModelのインスタンスが含まれている、その対応するView Modelで、 この子Viewを埋め込むために、そのDataContextは、MainWindowのViewモデルのプロパティに設定されます。
Viewをサポートするために、ViewModelを実装する
Implementing the View Model to Support the View
QuestionnaireViewModel.csファイルを開きます。 ViewModelは、アンケ-卜用紙とAllColorsプロパティを実装して、BindableBaseクラスから派生します。
C#
public class QuestionnaireViewModel : BindableBase
{
private Questionnaire questionnaire;
public QuestionnaireViewModel()
{
this.Questionnaire = new Questionnaire();
this.AllCollors = new[] { “Red”, “Blue”, “Green” };
}
public Questionnaire Questionnaire
{
get { return this.questionnaire; }
set { SetProperty(ref this.questionnaire, value); }
}
public IEnumerable<string> AllCollors { get; private set; }
}
INotifyPropertyChangedインターフェイスは、BindableBase基底クラス上で実装されます。 プロパティの変更通知は、次のコードで、紹介される、BindableBaseクラスのSetPropertyメソッドを使用して、全体のQuestionnaireプロパティに追加されます。
C#
public Questionnaire Questionnaire
{
get { return this.questionnaire; }
set { SetProperty(ref this.questionnaire, value); }
}
備考
一般的にView Modelクラスは、BindableBaseクラスから派生します。 場合によっては、Modelは、プロパティが、Viewを更新するために、 必要となるとき、その値が、変更され、モデルに格納されるとき、BindableBaseから派生することができます。
INotifyPropertyChangedに対応するために、あなたのクラスは、BindableBaseクラスから派生する必要があります。 そして、プロパティ・セッターは、BindableBaseクラスのSetPropertyメソッドを呼び出す必要があります。
次に示すコードは、BindableBaseクラスが、どのようにINotifyPropertyChangedインターフェイスを実装するかを示しています。 プロパティが、その値を変更するとき、SetPropertyメソッドが、プロパティの値を更新して、PropertyChangedイベントを発生することに注意します。 他の方法として、あなたは、PropertyChangedイベントを発生するために、プロパティを参照し、ラムダ式にそれを渡す、OnPropertyChangedメソッドを使用することができます。 これは、他のプロパティの更新でトリガされ、1つのプロパティが更新されるとき役に立ちます。そのうえ、Prismの以前のバージョンに、下位互換性を提供します。
C#
public abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (object.Equals(storage, value)) return false;
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged(string propertyName)
{
var eventHandler = this.PropertyChanged;
if (eventHandler != null)
{
eventHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
protected void OnPropertyChanged<T>(Expression<Func<T>> propertyExpression)
{
var propertyName = PropertySupport.ExtractPropertyName(propertyExpression);
this.OnPropertyChanged(propertyName);
}
}
メソッドは、使用されます。アンケ-卜用紙プロパティが、その値を変更し、 そして、ユーザー・インターフェイスを更新する時のように、どんなViewでも、ViewModelで、データが、変更するかもしれません。 そして、あなたは、画面上に、それらの変更が反映されることを望みます。 あなたは、ViewModelで、すべてのプロパティのため、このパターンを実装する必要があります。
アンケ-卜用紙プロパティ、コレクション・プロパティとコマンド・プロパティは、Viewモデル・クラスのコンストラクタで初期化されます。
C#
public QuestionnaireViewModel()
{
this.questionnaire = new Questionnaire();
this.AllColors = new[] { "Red", "Blue", "Green" };
}
コレクション・プロパティは、常に、空のコレクション、あるいは、それが、適切な場合、コンストラクタで、コレクションを埋め込むための、 どちらかを初期化する必要があります。あなたは、一般的に、サービスを呼び出すことによって、行うことができます。 あなたが、それを行う場合、それは、あなたが、デザイナーを分割しない方法で、それを行うことを確認します。
さらに、あなたが、ICommandプロパティを公開する場合、 Viewが、コマンド・プロパティのインスタンスを作成する必要があるコマンド・オブジェクトに結合できます。 この場合、なぜなら、あなたは、Prismから、DelegateCommand型を使用するでしょう。 あなたは、インスタンスを作成し、そして、処理メソッドを示す必要があります。 また、DelegateCommandは、厳密に型指定されたパラメータにそって、運ぶ能力があります。 また、ソース・コントロールのCommandParameterプロパティが設定されている場合、 これは、QuickStartで使用されないので、引数の型は、単に、オブジェクトとして指定されます。
次に示すコードは、MainWindowViewModelクラスに配置されている、OnSubmitハンドラ・メソッドを示しています。
C#
private void OnSubmit(object obj)
{
Debug.WriteLine(BuildResultString());
}
簡単なソリューションを維持するために、このハンドラ・メソッドは、 ヘルパー・メソッドの助けを借りてVisual Studioで、Outputウィンドウへの質問のために入力された値を返します。 それは、いつも、View Modelクラスで実装されます。 コマンド・ハンドラの実際の実装は、一般的に、結果をリポジトリに保存するか、 データを取り出すために、サービスや何かの呼び出しが行われるでしょう。 それが、操作の読み込み型の場合、また、ナビゲーション・サービスを呼び出すことによって、 ナビゲーションに、他のビューが、発生するかもしれません。
ViewModelにView要素を接続する
Wiring Up the View Elements to the View Model
View要素の結合は、次の表に示すように、View Modelプロパティを指します。 これらの結合が、MainWindow ViewとQuestionnaireView View内の両方に配置されることに注意してください。
Element name | Property | Value |
---|---|---|
NameTextBox | Text | {Binding Path= Questionnaire.Name, Mode=TwoWay} |
AgeTextBox | Text | {Binding Path=Questionnaire.Age, Mode=TwoWay} |
Question1Response | Text | {Binding Path=Questionnaire.Quest, Mode=TwoWay} |
ColorRun | Foreground | {Binding Questionnaire.FavoriteColor, TargetNullValue=Black} |
Colors | ItemsSource | {Binding Path=AllColors} |
Colors | SelectedItem | {Binding Questionnaire.FavoriteColor, Mode=TwoWay} |
SubmitButton | Command | {Binding SubmitCommand} |
ResetButton | Command | {Binding ResetCommand} |
ViewとView modelを作成して、それらを接続する
Creating the View and View Model and Hooking Them Up
ViewでViewModeをフックする、いくつかの方法があります。あなたは、背後にある、Viewコード内にViewModelを作成することができます。 そして、それを、そのDataContextプロパティ内に設定する、あるいは、宣言的に、それをViewのxamlコード内に設定します。 XAML内で、ViewModeのインスタンスを生成するために、View Modelクラスは、既定のコンストラクタを持っている必要があります。
もう一つの方法は、コンポーネントを作成することです。それは、対応するView Modelを配置できます。 そして、自動的に、それをDataContextに配置します。このコンポーネントは、一般的に、View Modelロケーターと呼ばれます。
Prismは、添付プロパティのView Modelロケーター・パターンの実装を提供します。
MainWindow.xamlを開き、View Modelロケーター・プロパティが添付されるコードを探します。 添付プロパティは、次のコードの最終行で紹介されています。
XAML
<Window x:Class="BasicMVVMQuickstart_Desktop.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:basicMvvmQuickstartDesktop="clr-namespace:BasicMVVMQuickstart_Desktop"
xmlns:viewModel="clr-namespace:Microsoft.Practices.Prism.Mvvm;assembly=Microsoft.Practices.Prism.Mvvm.Desktop"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:BasicMVVMQuickstart_Desktop.Views"
mc:Ignorable="d"
Title="Basic MVVM Quickstart"
Height="350"
Width="525"
d:DataContext="{d:DesignInstance basicMvvmQuickstartDesktop:QuestionnaireViewDesignViewModel, IsDesignTimeCreatable=True}"
viewModel:ViewModelLocator.AutoWireViewModel="True">
PrismのView Modelロケーターは、添付プロパティです。trueに設定すると、ViewのView Modelを配置することを試すでしょう。 そして、その次に、Viewのデータ・コンテクストを、View Modelのインスタンスに設定します。対応するView Modelを配置するために、 View Modelロケーターは、2つの方法を使用します。最初に、それは、マッピングしているView名前/ViewModel登録で、 ViewModelを探します。登録が見つからない場合、それは、置き換えることによって、ViewModelを配置する規則に基づいた方法に、戻します。 View名前空間から、「.View」と一緒に「.ViewModel」、 そして、Viewの名前に「ViewModel」を添付します。ViewModelにViewをフックする方法の詳細については; 「MVVMパターンを実装する」を参照してください。
設計時のサポートを追加する
あなたが、View Modelロケーターを使用すると、あなたのViewModelは、実行時に、作成されます。 その結果、あなたが、Viewを設計しているとき、View Modelは、まだ構築されていません。 そして、あなたは、設計間に、ViewModelデータを見ることはできません。
この状況を解決するために、あなたは、d:DataContextデザイナー・プロパティを使用することができます。
そして、それを設計時に作成された、特別なView Modelに設定します。このView Modelは、設計にのみ構築されます。 それは、本物のView Modelを簡略化したものです。そして、モック・データが、含まれるかもしれません。
次のコードでは、あなたは、このプロパティが、どのようにMainWindowページで使用されるか、見ることができます。
XAML
d:DataContext="{d:DesignInstance basicMvvmQuickstartDesktop:QuestionnaireViewDesignViewModel, IsDesignTimeCreatable=True}"
あなたが、DesignInstanceとして使用されるクラスを指定する必要があることに注意します。 そして、その次に、IsDesignTimeCreatableプロパティをtrueに設定します。 デザインView Modelクラスは、クラスで、DesignInstanceとして使用されます。 それは、既定のコンストラクタを持っている必要があります。
次のコードで、あなたは、クイックスタートのためのデザインView Modelが、どのように定義されるか、確かめることができます。
C#
public class QuestionnaireViewDesignViewModel
{
public QuestionnaireViewDesignViewModel()
{
this.QuestionnaireViewModel = new QuestionnaireViewModel();
}
public QuestionnaireViewModel QuestionnaireViewModel { get; set; }
}
このデザインView Modelは、結合するために、Viewで使用するプロパティを初期化する、そして、モック・データをそれらに埋め込む必要があります。 それは、デザインのためにだけ使用されるため、それは、BindableBaseから派生する必要も、INotifyPropertyChangedインターフェイスを実装する必要もありません。
詳細情報
More Information
MVVMパターンを実装するための詳細については、次のトピックを参照してください。:
Prismに含まれる、他のコードサンプルについて学ぶためには、 次のトピックを参照してください。:
Prism Library 5.0 for WPFを使用するMVVMコードサンプル
MVVM Code Sample using the Prism Library 5.0 for WPF(原文)
分離したView Modelクラス内のViewから、状態とViewロジックに、 そして、モデル・クラス内のアプリケーション・データ・モデルをどのように分離するか学習するために、このサンプルをダウンロードしてください。
概要
Introduction
Model-View-ViewModel(MVVM)クイックスタートは、状態とロジックをどのように分離するかを説明するサンプルコードを提供します。 それは、Prismライブラリを使用して、ViewModelという名前の分離したクラスに、Viewをサポートします。 Viewをサポートするために必要な状態やデータを提供するために、View Modelは、アプリケーション・データ・モデルの上で位置します。 アプリケーションの完全な複雑さを知っている必要から、Viewを隔離します。 また、View Modelは、View要素それ自体に直接依存しない、Viewのための相互作用ロジックをカプセル化します。 このクイックスタートでは、MVVMパターンを実装することに関するチュートリアルを提供します。
MVVMアプリケーションで、ViewとView Modelを設計する一般的な方法は、 最初に、どのViewが画面上で見えるか、ストーリーボードをスケッチします。続いて、あなたは、その画面を識別するために、分析します。 View Modelのどんなプロパティが、Viewをサポートするために、公開する必要があるか、そのデータが、どのようにViewModelになるか気にすることなく、 あなたは、どんなView Modelを、Viewに公開する必要があるか定義し、それを実装した後に、 あなたは、続いて、どのように、データをView Modelに取得するかに、飛び込むことができます。 多くの場合、これは、ViewModelが、データを取り出すために、サービスを呼び出すことを含んでいます。 そして、ときどき、データは、アプリケーション・コントロールのような、いくつかの他のコードから、ViewModelに、押しこむことができます。
このクイックスタートは、あなたを、次の手順に案内します。:
- どんな状態が、それをサポートするために、ViewModelに必要か決定するためにViewを分析します。
- Viewをサポートするために、View Modelクラスと最小の実装を定義します。
- View Modelプロパティを指すViewで結合を定義する
- ViewをView Modelに添付する
サンプルの構築
Building the Sample
- Visual Studioで、ソリューション・ファイルBasicMVVMQuickstart_Desktop\BasicMVVMQuickstart_Desktop.slnを開きます。
- Buildメニューで、ソリューションのリビルドをクリックします。
- QuickStartを実行するために、F5を押してください。
詳細情報
More Information
MVVMクイックスタートの詳細については、MSDNの上で関連する文書(原文)を参照してください。