【13 c 2】デベロッパーに贈る!m-v-vmパターンで造るwpfアプリケーション
DESCRIPTION
Developers Summit 2009 2/13(金)11:10~11:55 C(華うたげ)TRANSCRIPT
![Page 1: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/1.jpg)
グレープシテゖ株式会社
八巻 雄哉
![Page 2: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/2.jpg)
![Page 3: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/3.jpg)
ソフトウェゕ事業歴 25 年超
文化オリエント株式会社( BOC )1980.05 ~ 2001.12
1983年 私学会計システム Leyser 販売開始
コンポーネントと共に歩んで15年
1993年 PowerTools® 販売開始
Visual Basic 用コンポーネント( VBX → OCX → ActiveX )
2000年 Java対応コンポーネント販売開始
2002年 PowerTools® for .NET 販売開始
2008年 PowerTools® シリーズ15周年
![Page 4: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/4.jpg)
ソフトウェゕを Model / View / ViewModelの3つに分けて構築するWPFゕプリケーションに適用可能なソフトウェゕゕーキテクチャ
![Page 5: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/5.jpg)
MVC( Model / View / Controller )
ソフトウェゕゕーキテクチャはフレームワークに依存する。
M-V-VMはWPF UIフレームワーク版MVC
![Page 6: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/6.jpg)
UIとロジックの分離
各コンポーネント間の依存性を最小限に
UIではなくロジックを主体とした開発
![Page 7: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/7.jpg)
保守性(変更耐性)
再利用性
テスト容易性
分業
![Page 8: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/8.jpg)
Model(DataModel) ゕプリケーションが扱う
データと手続きを表現する要素
View データを視覚化して表示する要素
ユーザー操作を受け取る要素
ViewModel Viewのために最適化されたModel
Viewのデータと状態を管理する要素
ViewとModelのゕダプター
![Page 9: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/9.jpg)
ViewXAML
最小限のコードビハンド
ViewModel
Viewに最適化されたModel、コマンド
Unit Test
コマンドバンデゖング データバンデゖング
Model
データ、業務ロジック
データの受け渡し 業務フゔンクションの実行
テストメソッド
![Page 10: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/10.jpg)
① データバインディング
System.Windows.Data.Bindingクラス
INotifyPropertyChangedンターフェス
IDataErrorInfoンターフェス
② コマンド
System.Windows.Input.ICommandンターフェス
ICommandSourceンターフェス
![Page 11: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/11.jpg)
ソフトウェゕゕーキテクチャに「ただひとつの真の実装」は存在しない。
![Page 12: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/12.jpg)
BMI測定ゕプリケーション
![Page 13: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/13.jpg)
Demo 0
![Page 14: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/14.jpg)
Bindingオブジェクト
2つの異なるオブジェクトのプロパテゖ値を同期
バンデゖングオブジェクト
バンデゖングソース
バンデゖングターゲット
UI要素 データオブジェクト
依存関係プロパテゖ
プロパテゖ
OneWay
TwoWay
OneWayToSource
![Page 15: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/15.jpg)
TextBox
Textプロパテゖ Heightプロパテゖ
Weightプロパテゖ
Personオブジェクト
TextBox
Textプロパテゖ
<TextBox Text="{Binding Weight,
Source={StaticResource person}}"/>
ソースターゲット
![Page 16: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/16.jpg)
FrameworkElement.DataContextプロパテゖ
Bindingオブジェクトごとにソースを指定するのではなく、共通のソースとして指定する場合に使用
DataContextプロパテゖに設定したソースオブジェクトは、子要素に継承される。
![Page 17: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/17.jpg)
TextBox
Textプロパテゖ Heightプロパテゖ
Weightプロパテゖ
Personオブジェクト
TextBox
Textプロパテゖ
<TextBox Text="{Binding Weight}"/>
DataContextプロパテゖ
this.DataContext = new Person();
ソースターゲット
![Page 18: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/18.jpg)
Demo 10
![Page 19: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/19.jpg)
ソースのプロパテゖ値が変更されたことをターゲットに通知するためにソース側に必要なンターフェス
ソース側の各プロパテゖが変更された際に、PropertyChangedベントを発生させるように実装する。
class Person : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
![Page 20: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/20.jpg)
public double Bmi
{
get { return _bmi; }
private set
{
_bmi = value;
this.OnPropertyChanged("Bmi");
}
}
void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
![Page 21: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/21.jpg)
TextBox
Textプロパテゖ Bmiプロパテゖ
Calculateメソッド
Personオブジェクト
Bmi = Weight / Math.Pow(Height, 2);
ソースターゲット
this.OnPropertyChanged("Bmi");
2020
![Page 22: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/22.jpg)
Demo 11
![Page 23: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/23.jpg)
ModelView
![Page 24: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/24.jpg)
ViewXAML
最小限のコードビハンド
Model
データ、業務ロジック
業務フゔンクションの実行
データバンデゖング
![Page 25: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/25.jpg)
「身長」、「体重」のデフォルトを、未入力状態とする。
ModelのHeightとWeightはdouble型
Modelと直接バンドすると、未入力状態にはできない。
![Page 26: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/26.jpg)
View
ViewModelHeight
データバンデゖング
Model
string型
Heightdouble型
入力データ検証
• string.IsNullOrEmpty• double.TryParse
データ受け渡し
エラー通知
![Page 27: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/27.jpg)
WPFにおける入力データの検証は、データバンデゖングのプロセスの1つとして行われる。
バンデゖングオブジェクト
バンデゖングソース
バンデゖングターゲット
UI要素 データオブジェクト
依存関係プロパテゖ プロパテゖ検証 変換
![Page 28: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/28.jpg)
検証はBinding.ValidationRulesプロパテゖに設定されたルールに基づいて行われる。
既定で用意されているルールは2つ
ExceptionValidationRule
DataErrorValidationRule(WPF 3.5から)
ソースオブジェクトのIDataErrorInfoンターフェス実装で発生するエラーをチェックする検証ルール
![Page 29: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/29.jpg)
<TextBox>
<TextBox.Text>
<Binding Path="Height">
<Binding.ValidationRules>
<DataErrorValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
Text="{Binding Height, ValidatesOnDataErrors=true}"
簡略記法
![Page 30: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/30.jpg)
Binding.ValidatesOnDataErrorsプロパテゖ
trueに設定することで、ValidationRulesプロパテゖにDataErrorValidationRuleを設定した状態になる。
ちなみにExceptionValidationRuleでも同様のプロパテゖあり
Text="{Binding Height, ValidatesOnDataErrors=true}"
Text="{Binding Height, ValidatesOnExceptions=true}"
![Page 31: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/31.jpg)
Errorプロパテゖ
オブジェクトに関するエラーメッセージを返す。
Itemプロパテゖ(ンデクサ)
指定した名前のプロパテゖに関するエラーメッセージを返す。
![Page 32: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/32.jpg)
public string this[string columnName]
{
get
{
string msg = null;
if (columnName == "Height")
{
if (string.IsNullOrEmpty(Height))
msg = "未入力";
}
return msg;
}
}
![Page 33: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/33.jpg)
TextBox
Heightプロパテゖ
class PersonViewModel: IDataErrorInfo
ソースターゲット
1a
検証
public string this[string columnName]
バンドしているプロパテゖ名でンデクサを参照
Validation.Errors添付プロパテゖにValidationErrorが追加される。 戻り値:
エラーメッセージ
ンデクサ
Textプロパテゖ
Text="{Binding Height, ValidatesOnDataErrors=true}"
1a
![Page 34: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/34.jpg)
Validation.Errors添付プロパテゖにValidationErrorが存在する場合、エラーテンプレートが表示される。
Validation.ErrorTemplate添付プロパテゖ(ControlTemplate型)
任意のControlTemplateを定義することでUI上のフゖードバックをカスタマズ可能
![Page 35: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/35.jpg)
Demo 20
![Page 36: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/36.jpg)
有効な値が入力されていない場合には、「計算」ボタンを無効な状態にしたい。
![Page 37: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/37.jpg)
そもそもベントハンドラを1行も書かないって話は?
private void ButtonStateUpadate()
{
if (string.IsNullOrEmpty(_textbox1.Text) || string.IsNullOrEmpty(_textbox2.Text))
_button1.IsEnabled = false;
else
_button1.IsEnabled = true;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
((Person)this.DataContext).Calculate();
}
![Page 38: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/38.jpg)
実行ロジックを切り離して、再利用可能にする仕組み
コマンドを作成しViewModelのプロパテゖとして公開することで、Viewはバンデゖングを利用して実行ロジックを呼び出すことができる。
![Page 39: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/39.jpg)
ICommandSourceンターフェスを実装したクラス
既定で存在するコマンドソース
ButtonBase
Button、CheckBox、RadioButtonなど
Hyperlink
MenuItem
![Page 40: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/40.jpg)
ICommandンターフェス
CanExecuteメソッド
現在の状態でこのコマンドを実行できるかどうかを判断するメソッド
Executeメソッド
コマンド実行時に呼び出されるメソッド
CanExecuteChangedベント
コマンドを実行するかどうかに影響するような変更があった場合に発生
![Page 41: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/41.jpg)
Calcプロパテゖ
ViewModel
コマンドソース プロパテゖとしてコマンドを公開
public ICommand Calc
コマンド
Executeメソッド
実行処理実行可能かどうかを判断し、不可の場合
にはfalseを返す
CanExecuteメソッド
private class CalcCommand
: ICommand
Commandプロパテゖ
<Button Command="{Binding Calc}"/>
CanExecuteChangedベント
実行の可否が変化した際に発生させる
Heightプロパテゖ
1a
![Page 42: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/42.jpg)
Demo 21
![Page 43: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/43.jpg)
View
Model
ViewModel
![Page 44: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/44.jpg)
① テスト容易性
単体テストが簡単に書けるか?
② 再利用性
修正を行わずに、Viewを差し替えることができるか?
![Page 45: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/45.jpg)
Demo 30
![Page 46: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/46.jpg)
Demo 40
![Page 47: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/47.jpg)
まずはデータバンデゖングを使ってModel-Viewから始めよう。
こうなったときはViewModelの出番
ViewとModelが直接バンドすると何かと都合が悪い
実装すべき場所がViewでもModelでもないコードがある
ViewModelに対する単体テストを書いてテストを自動化しよう。
![Page 48: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/48.jpg)
宣言的に記述されるバンデゖングはデバッグが困難
Visual Studio 2010に期待
規模が小さく単純なゕプリケーションでは割に合わない。
ソフトウェゕゕーキテクチャに「ただひとつの真の実装」は存在しない。
是非GrapeCityブースにお立ち寄りください。
![Page 49: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/49.jpg)
2008J Enterprise
Windowsフォーム、ASP.NETに加え、グリッド、チャート、スケジュール、レポート
の4つのWPFコンポーネントが新登場
http://www.grapecity.com/japan/c1/
![Page 50: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/50.jpg)
Tales from the Smart Clienthttp://blogs.msdn.com/johngossman/
Dan Crevier's Bloghttp://blogs.msdn.com/dancre/
Josh Smith on WPFhttp://joshsmithonwpf.wordpress.com/
Karl On WPF - .Nethttp://karlshifflett.wordpress.com/
CodeProject. Free source code and programming help
http://www.codeproject.com/
![Page 51: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション](https://reader031.vdocuments.site/reader031/viewer/2022020115/5463d9b2b4af9f583f8b4700/html5/thumbnails/51.jpg)
Developers Summit 2009
『デベロッパーに贈る!M-V-VMパターンで作るWPFアプリケーション』
2009年2月13日グレープシテゖ株式会社 ツール事業部 テクニカルエバンジェリスト
Microsoft MVP for Development Platforms - Client App Dev Jan 2009 - Dec 2009
八巻 雄哉http://d.hatena.ne.jp/Yamaki/
InputMan for WPF絶賛開発中!!