【13 c 2】デベロッパーに贈る!m-v-vmパターンで造るwpfアプリケーション
Post on 12-Nov-2014
6.466 Views
Preview:
DESCRIPTION
TRANSCRIPT
グレープシテゖ株式会社
八巻 雄哉
ソフトウェゕ事業歴 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周年
ソフトウェゕを Model / View / ViewModelの3つに分けて構築するWPFゕプリケーションに適用可能なソフトウェゕゕーキテクチャ
MVC( Model / View / Controller )
ソフトウェゕゕーキテクチャはフレームワークに依存する。
M-V-VMはWPF UIフレームワーク版MVC
UIとロジックの分離
各コンポーネント間の依存性を最小限に
UIではなくロジックを主体とした開発
保守性(変更耐性)
再利用性
テスト容易性
分業
Model(DataModel) ゕプリケーションが扱う
データと手続きを表現する要素
View データを視覚化して表示する要素
ユーザー操作を受け取る要素
ViewModel Viewのために最適化されたModel
Viewのデータと状態を管理する要素
ViewとModelのゕダプター
ViewXAML
最小限のコードビハンド
ViewModel
Viewに最適化されたModel、コマンド
Unit Test
コマンドバンデゖング データバンデゖング
Model
データ、業務ロジック
データの受け渡し 業務フゔンクションの実行
テストメソッド
① データバインディング
System.Windows.Data.Bindingクラス
INotifyPropertyChangedンターフェス
IDataErrorInfoンターフェス
② コマンド
System.Windows.Input.ICommandンターフェス
ICommandSourceンターフェス
ソフトウェゕゕーキテクチャに「ただひとつの真の実装」は存在しない。
BMI測定ゕプリケーション
Demo 0
Bindingオブジェクト
2つの異なるオブジェクトのプロパテゖ値を同期
バンデゖングオブジェクト
バンデゖングソース
バンデゖングターゲット
UI要素 データオブジェクト
依存関係プロパテゖ
プロパテゖ
OneWay
TwoWay
OneWayToSource
TextBox
Textプロパテゖ Heightプロパテゖ
Weightプロパテゖ
Personオブジェクト
TextBox
Textプロパテゖ
<TextBox Text="{Binding Weight,
Source={StaticResource person}}"/>
ソースターゲット
FrameworkElement.DataContextプロパテゖ
Bindingオブジェクトごとにソースを指定するのではなく、共通のソースとして指定する場合に使用
DataContextプロパテゖに設定したソースオブジェクトは、子要素に継承される。
TextBox
Textプロパテゖ Heightプロパテゖ
Weightプロパテゖ
Personオブジェクト
TextBox
Textプロパテゖ
<TextBox Text="{Binding Weight}"/>
DataContextプロパテゖ
this.DataContext = new Person();
ソースターゲット
Demo 10
ソースのプロパテゖ値が変更されたことをターゲットに通知するためにソース側に必要なンターフェス
ソース側の各プロパテゖが変更された際に、PropertyChangedベントを発生させるように実装する。
class Person : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
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));
}
TextBox
Textプロパテゖ Bmiプロパテゖ
Calculateメソッド
Personオブジェクト
Bmi = Weight / Math.Pow(Height, 2);
ソースターゲット
this.OnPropertyChanged("Bmi");
2020
Demo 11
ModelView
ViewXAML
最小限のコードビハンド
Model
データ、業務ロジック
業務フゔンクションの実行
データバンデゖング
「身長」、「体重」のデフォルトを、未入力状態とする。
ModelのHeightとWeightはdouble型
Modelと直接バンドすると、未入力状態にはできない。
View
ViewModelHeight
データバンデゖング
Model
string型
Heightdouble型
入力データ検証
• string.IsNullOrEmpty• double.TryParse
データ受け渡し
エラー通知
WPFにおける入力データの検証は、データバンデゖングのプロセスの1つとして行われる。
バンデゖングオブジェクト
バンデゖングソース
バンデゖングターゲット
UI要素 データオブジェクト
依存関係プロパテゖ プロパテゖ検証 変換
検証はBinding.ValidationRulesプロパテゖに設定されたルールに基づいて行われる。
既定で用意されているルールは2つ
ExceptionValidationRule
DataErrorValidationRule(WPF 3.5から)
ソースオブジェクトのIDataErrorInfoンターフェス実装で発生するエラーをチェックする検証ルール
<TextBox>
<TextBox.Text>
<Binding Path="Height">
<Binding.ValidationRules>
<DataErrorValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
Text="{Binding Height, ValidatesOnDataErrors=true}"
簡略記法
Binding.ValidatesOnDataErrorsプロパテゖ
trueに設定することで、ValidationRulesプロパテゖにDataErrorValidationRuleを設定した状態になる。
ちなみにExceptionValidationRuleでも同様のプロパテゖあり
Text="{Binding Height, ValidatesOnDataErrors=true}"
Text="{Binding Height, ValidatesOnExceptions=true}"
Errorプロパテゖ
オブジェクトに関するエラーメッセージを返す。
Itemプロパテゖ(ンデクサ)
指定した名前のプロパテゖに関するエラーメッセージを返す。
public string this[string columnName]
{
get
{
string msg = null;
if (columnName == "Height")
{
if (string.IsNullOrEmpty(Height))
msg = "未入力";
}
return msg;
}
}
TextBox
Heightプロパテゖ
class PersonViewModel: IDataErrorInfo
ソースターゲット
1a
検証
public string this[string columnName]
バンドしているプロパテゖ名でンデクサを参照
Validation.Errors添付プロパテゖにValidationErrorが追加される。 戻り値:
エラーメッセージ
ンデクサ
Textプロパテゖ
Text="{Binding Height, ValidatesOnDataErrors=true}"
1a
Validation.Errors添付プロパテゖにValidationErrorが存在する場合、エラーテンプレートが表示される。
Validation.ErrorTemplate添付プロパテゖ(ControlTemplate型)
任意のControlTemplateを定義することでUI上のフゖードバックをカスタマズ可能
Demo 20
有効な値が入力されていない場合には、「計算」ボタンを無効な状態にしたい。
そもそもベントハンドラを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();
}
実行ロジックを切り離して、再利用可能にする仕組み
コマンドを作成しViewModelのプロパテゖとして公開することで、Viewはバンデゖングを利用して実行ロジックを呼び出すことができる。
ICommandSourceンターフェスを実装したクラス
既定で存在するコマンドソース
ButtonBase
Button、CheckBox、RadioButtonなど
Hyperlink
MenuItem
ICommandンターフェス
CanExecuteメソッド
現在の状態でこのコマンドを実行できるかどうかを判断するメソッド
Executeメソッド
コマンド実行時に呼び出されるメソッド
CanExecuteChangedベント
コマンドを実行するかどうかに影響するような変更があった場合に発生
Calcプロパテゖ
ViewModel
コマンドソース プロパテゖとしてコマンドを公開
public ICommand Calc
コマンド
Executeメソッド
実行処理実行可能かどうかを判断し、不可の場合
にはfalseを返す
CanExecuteメソッド
private class CalcCommand
: ICommand
Commandプロパテゖ
<Button Command="{Binding Calc}"/>
CanExecuteChangedベント
実行の可否が変化した際に発生させる
Heightプロパテゖ
1a
Demo 21
View
Model
ViewModel
① テスト容易性
単体テストが簡単に書けるか?
② 再利用性
修正を行わずに、Viewを差し替えることができるか?
Demo 30
Demo 40
まずはデータバンデゖングを使ってModel-Viewから始めよう。
こうなったときはViewModelの出番
ViewとModelが直接バンドすると何かと都合が悪い
実装すべき場所がViewでもModelでもないコードがある
ViewModelに対する単体テストを書いてテストを自動化しよう。
宣言的に記述されるバンデゖングはデバッグが困難
Visual Studio 2010に期待
規模が小さく単純なゕプリケーションでは割に合わない。
ソフトウェゕゕーキテクチャに「ただひとつの真の実装」は存在しない。
是非GrapeCityブースにお立ち寄りください。
2008J Enterprise
Windowsフォーム、ASP.NETに加え、グリッド、チャート、スケジュール、レポート
の4つのWPFコンポーネントが新登場
http://www.grapecity.com/japan/c1/
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/
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絶賛開発中!!
top related