半人前プログラマーの技術談議

開発した物と,C#を入門者向けに解説した記事を書いています!

【C# GUI】MVVM① データバインディング part4-7【WPF XAML】

calendar

reload

【C# GUI】MVVM① データバインディング part4-7【WPF XAML】

こんにちは!シロウです!

今回はMVVMとデータバインディングについて紹介します!

長くなってしまったので3回に分けます!

MVVM

概要

MVVMは,Model,View,ViewModelの3つの役割に分類する事です.

part4-3で紹介したMVCとほぼ変わりません.

ControllerがViewModelになっただけです.

今回はViewは前回作ったものを使用し,

Modelはpart4-3で使用したものと同じものを使用するので,

ViewModelを開発することになります.

 

MVVM開発

プロジェクトの取り込み

Modelのデータを持っていない方は,こちらからダウンロードをお願いします.

ダウンロードできたら,展開してわかりやすい場所に置いてください.

 

画面左上のファイルメニューから,追加→既存のプロジェクトの順に選択します.

ダウンロードしたプロジェクトファイルを選択します.

ソリューションエクスプローラーでRandomNumberプロジェクトが追加されたことが確認できたらOKです.

次に,参照の追加をします.

ソリューションエクスプローラーから,WPF_RandomNumberプロジェクトの参照を右クリックし,参照の追加を選択します.

表示された参照マネージャーダイアログボックスの左メニューから「プロジェクト」を選択し,

RandomNumberプロジェクトにチェックを入れてOKをクリックします.

ソリューションエクスプローラーで,WPF_RandomNumberプロジェクトの参照に,

RandomNumberプロジェクトが追加されていればOKです.

 

ViewModelクラスの作成

WPF_RandomNumberを右クリックして,追加→クラスの順に選択します.

名前はMainWindowのViewModelなので,「MainWindowVM」にします.

 

ViewModelクラスの実装

基本的には,MVCのControllerと変わりません.

RandomNumberプロジェクトのProgramクラスのMainメソッドを確認しましょう.

最初に,文字数の情報を受け渡しする為に,NumOfStringプロパティを宣言します.

初期値は10に設定します.

次に,Randomクラスを宣言し,コンストラクタで初期化します.

 

データバインディング

データバインディングは,ViewのUI要素とViewModelのプロパティを通信を可能にする機能です.

UI要素(XAML)に数行のコードを追加するだけでこの機能を使うことができます.WPFの特徴の1つです.

最初に,インテリセンスを使用する為に,画面上部のビルドメニューからソリューションのビルドを選択します.

次に,MainWindow.xamlのWindowタグ内に,Window要素のDataContextプロパティにViewModelを設定します.

DataContextに設定されたクラスは,このViewに関連付けられます.

クラスを値に設定するときは,名前空間から記述する必要があります.

MainWindowVMクラスの名前空間は,WPF_RandomNumberです.

Window要素でlocalというエイリアスが付けられているので,「local:」をクラス名の前に記述しています.

MainWindowクラス(MainWindow.xaml.cs)のインスタンスが生成されると,

DataContextプロパティに設定されているクラスのインスタンスがすぐに生成されます.

MainWindowクラスとMainWindowVMクラスが関連付けられるので,MainWindowクラス(View)は,MainWindowクラス(ViewModel)のプロパティとデータを受け渡しできるようになります.

 

UI要素とViewModelのプロパティをバインドします.

文字数を設定するテキストボックスのTextプロパティにNumOfStringプロパティをバインドします.

{}を使って,Bindingの後にMainWindowVMクラスのプロパティ名を記述します.

実行すると,初期値に設定した10が表示されていることが確認できます.

Viewクラス(MainWindow.xaml.cs)に1行もコードをせず,ViewModelクラス(MainWindowVM.cs)とデータの双方向通信ができる.

これがデータバインディングの特徴です.

 

実際に動きを見る為に,NumOfStringプロパティを少し書き換えて,ブレークポイントを設定して確認できるようにしてみます.

setアクセサーの行にカーソルを置き,画面上部のデバックメニューからブレークポイントの設定/解除をクリックします.

デバッグメニューから,デバッグの開始を選択して実行します.

設定したブレークポイントでプログラムが一時的に停止しますが,そのまま続行を押します.

テキストボックスの値を10から5に変更します.

変更後,他のUI要素にフォーカスを移動させます.ここでは,隣の数字列作成のボタンを押します.

ブレークポイントを設定したsetアクセサーの行のコードでプログラムが一時停止します.

この状態でnumofstring変数とvalue変数にカーソルを当てて値を確認します.

確認できたら,ステップイン(1行ずつ)実行をします.

ステップインは画面上部のデバッグからステップインを選択するか,ショートカットから実行します.

value変数の値がnumofstring変数に格納されます.

まとめると,テキストボックスで入力した値(View側)がプロパティ(ViewModel側)によって値が更新されているという事です.

データバインディングの通信が確認できたと思います.

 

プロパティの値の更新のタイミング

ブレークポイントでデータバインディングの通信を確認した時,

他のUI要素にフォーカスを移動したときにvalueに値が代入されていました.

テキストボックスのTextプロパティのバインドのUpdateSourceTriggerプロパティの初期値が,

LostFocusに設定されているからです.(負荷を減らす為)

この値をPropertyChangedに変更すると,値を変更した瞬間にプロパティ(value)の値が更新されます.

デバッグの開始を選択して実行すると確認できると思います.

ちなみに,他のUI要素の初期値はPropertyChangedに設定されています.(一部を除く)

 

まとめ

WPFの一番のメリットが,データバインディングによる通信と,MVVMで開発する事です.

ここまでの操作で,ViewはXAMLの記述だけで,クラスの記述はしていません.

つまり,UI部分は全てXAMLで作成し,MVCのViewに記述していたイベントハンドラーは,ViewModelでデータバインディングで記述しています.

Viewの比重を軽くしたとも言えそうですね.

次回は,アウトプット部分のUIのデータバインディングと,デリゲートコマンドについて紹介します.