WPF 扱うにあたって MVVM パターンをお勉強しておこうか…と思ったものの、思いのほか難しく半ば挫折したのでメモ(汗
元ネタはここ http://code.msdn.microsoft.com/windowsdesktop/MVVM-d8261534
元サイトの内容は、いろいろ凝ってて(計算処理が選べたり、DelegateCommand 実装したり、ラムダ式あったり、 yield return あったり、Generics あったり…と)、MVVM に行きつくまでの障壁が結構高い。
なので、超単純化してみました。単純化し過ぎて「これは MVVM じゃない」と言われると思うので「MVVM もどき」です(汗
- View(XAML)
特徴としては x:name 属性がないこと。
要するにコード側からは基本的にアクセスしない。<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="100" Width="400"> <StackPanel> <StackPanel Orientation="Horizontal"> <TextBox Text="{Binding A}" Width="100"/> <TextBlock Text="+"/> <TextBox Text="{Binding B}" Width="100"/> <TextBlock Text="=" /> <TextBlock Text="{Binding C}" Width="100"/> <Button Content="計算" Click="CalcButton" Width="50" /> </StackPanel> </StackPanel> </Window>
- View(コードビハインド)
MVVM ではコードビハインドは原則使用不可。
Click イベント類は、コマンドオブジェクトにして XAML から 直接 ViewModel へ転送するらしい。
…けど面倒なのでコードビハインドを使用(汗Class MainWindow ' ViewModel を New Private _viewModel As ViewModel = New ViewModel ' View の DataContext へ viewModel をバインド Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded Me.DataContext = _viewModel End Sub ' 操作類は、viewModel 側のメソッドで実行させたいので、転送する。 Private Sub CalcButton(sender As Object, e As RoutedEventArgs) _viewModel.Execute() End Sub End Class
- View-Model
View で表示するデータを置くところ。
View との結合は Binding で行い、直接コントロールは ViewModel からは操作しないようにする。
本来は、プロパティごとに PropertyChanged を発行する。そのために、ViewModelBase のような基底クラスを作ったりするようだが、今回の例では INotifyPropertyChanged を直接実装し、かつ、計算操作が行われたときに一括で更新するのみとした。Imports System.ComponentModel Public Class ViewModel Implements INotifyPropertyChanged Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) _ Implements INotifyPropertyChanged.PropertyChanged ' View に渡すデータ Public Property A As Integer ' 入力1 Public Property B As Integer ' 入力2 Public Property C As Integer ' 計算結果 ' 計算処理と View の更新 Public Sub Execute() ' 計算 C = Model.Calc(A, B) ' View を更新 RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("")) End Sub End Class
- Model
計算処理本体。今回は Shared(Static) メソッド。
変哲もない、ただの足し算(汗Public Class Model Public Shared Function Calc(a As Integer, b As Integer) As Integer Return a + b End Function End Class