【13 c 2】デベロッパーに贈る!m-v-vmパターンで造るwpfアプリケーション

51
グレープシテゖ株式会社 八巻 雄哉

Upload: yuya-yamaki

Post on 12-Nov-2014

6.467 views

Category:

Technology


6 download

DESCRIPTION

Developers Summit 2009 2/13(金)11:10~11:55 C(華うたげ)

TRANSCRIPT

Page 1: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

グレープシテゖ株式会社

八巻 雄哉

Page 2: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション
Page 3: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

ソフトウェゕ事業歴 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アプリケーション

ソフトウェゕを Model / View / ViewModelの3つに分けて構築するWPFゕプリケーションに適用可能なソフトウェゕゕーキテクチャ

Page 5: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

MVC( Model / View / Controller )

ソフトウェゕゕーキテクチャはフレームワークに依存する。

M-V-VMはWPF UIフレームワーク版MVC

Page 6: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

UIとロジックの分離

各コンポーネント間の依存性を最小限に

UIではなくロジックを主体とした開発

Page 7: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

保守性(変更耐性)

再利用性

テスト容易性

分業

Page 8: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

Model(DataModel) ゕプリケーションが扱う

データと手続きを表現する要素

View データを視覚化して表示する要素

ユーザー操作を受け取る要素

ViewModel Viewのために最適化されたModel

Viewのデータと状態を管理する要素

ViewとModelのゕダプター

Page 9: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

ViewXAML

最小限のコードビハンド

ViewModel

Viewに最適化されたModel、コマンド

Unit Test

コマンドバンデゖング データバンデゖング

Model

データ、業務ロジック

データの受け渡し 業務フゔンクションの実行

テストメソッド

Page 10: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

① データバインディング

System.Windows.Data.Bindingクラス

INotifyPropertyChangedンターフェス

IDataErrorInfoンターフェス

② コマンド

System.Windows.Input.ICommandンターフェス

ICommandSourceンターフェス

Page 11: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

ソフトウェゕゕーキテクチャに「ただひとつの真の実装」は存在しない。

Page 12: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

BMI測定ゕプリケーション

Page 13: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

Demo 0

Page 14: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

Bindingオブジェクト

2つの異なるオブジェクトのプロパテゖ値を同期

バンデゖングオブジェクト

バンデゖングソース

バンデゖングターゲット

UI要素 データオブジェクト

依存関係プロパテゖ

プロパテゖ

OneWay

TwoWay

OneWayToSource

Page 15: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

TextBox

Textプロパテゖ Heightプロパテゖ

Weightプロパテゖ

Personオブジェクト

TextBox

Textプロパテゖ

<TextBox Text="{Binding Weight,

Source={StaticResource person}}"/>

ソースターゲット

Page 16: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

FrameworkElement.DataContextプロパテゖ

Bindingオブジェクトごとにソースを指定するのではなく、共通のソースとして指定する場合に使用

DataContextプロパテゖに設定したソースオブジェクトは、子要素に継承される。

Page 17: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

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アプリケーション

Demo 10

Page 19: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

ソースのプロパテゖ値が変更されたことをターゲットに通知するためにソース側に必要なンターフェス

ソース側の各プロパテゖが変更された際に、PropertyChangedベントを発生させるように実装する。

class Person : INotifyPropertyChanged

public event PropertyChangedEventHandler PropertyChanged;

Page 20: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

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アプリケーション

TextBox

Textプロパテゖ Bmiプロパテゖ

Calculateメソッド

Personオブジェクト

Bmi = Weight / Math.Pow(Height, 2);

ソースターゲット

this.OnPropertyChanged("Bmi");

2020

Page 22: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

Demo 11

Page 23: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

ModelView

Page 24: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

ViewXAML

最小限のコードビハンド

Model

データ、業務ロジック

業務フゔンクションの実行

データバンデゖング

Page 25: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

「身長」、「体重」のデフォルトを、未入力状態とする。

ModelのHeightとWeightはdouble型

Modelと直接バンドすると、未入力状態にはできない。

Page 26: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

View

ViewModelHeight

データバンデゖング

Model

string型

Heightdouble型

入力データ検証

• string.IsNullOrEmpty• double.TryParse

データ受け渡し

エラー通知

Page 27: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

WPFにおける入力データの検証は、データバンデゖングのプロセスの1つとして行われる。

バンデゖングオブジェクト

バンデゖングソース

バンデゖングターゲット

UI要素 データオブジェクト

依存関係プロパテゖ プロパテゖ検証 変換

Page 28: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

検証はBinding.ValidationRulesプロパテゖに設定されたルールに基づいて行われる。

既定で用意されているルールは2つ

ExceptionValidationRule

DataErrorValidationRule(WPF 3.5から)

ソースオブジェクトのIDataErrorInfoンターフェス実装で発生するエラーをチェックする検証ルール

Page 29: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

<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アプリケーション

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アプリケーション

Errorプロパテゖ

オブジェクトに関するエラーメッセージを返す。

Itemプロパテゖ(ンデクサ)

指定した名前のプロパテゖに関するエラーメッセージを返す。

Page 32: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

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アプリケーション

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アプリケーション

Validation.Errors添付プロパテゖにValidationErrorが存在する場合、エラーテンプレートが表示される。

Validation.ErrorTemplate添付プロパテゖ(ControlTemplate型)

任意のControlTemplateを定義することでUI上のフゖードバックをカスタマズ可能

Page 35: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

Demo 20

Page 36: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

有効な値が入力されていない場合には、「計算」ボタンを無効な状態にしたい。

Page 37: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

そもそもベントハンドラを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アプリケーション

実行ロジックを切り離して、再利用可能にする仕組み

コマンドを作成しViewModelのプロパテゖとして公開することで、Viewはバンデゖングを利用して実行ロジックを呼び出すことができる。

Page 39: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

ICommandSourceンターフェスを実装したクラス

既定で存在するコマンドソース

ButtonBase

Button、CheckBox、RadioButtonなど

Hyperlink

MenuItem

Page 40: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

ICommandンターフェス

CanExecuteメソッド

現在の状態でこのコマンドを実行できるかどうかを判断するメソッド

Executeメソッド

コマンド実行時に呼び出されるメソッド

CanExecuteChangedベント

コマンドを実行するかどうかに影響するような変更があった場合に発生

Page 41: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

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アプリケーション

Demo 21

Page 43: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

View

Model

ViewModel

Page 44: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

① テスト容易性

単体テストが簡単に書けるか?

② 再利用性

修正を行わずに、Viewを差し替えることができるか?

Page 45: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

Demo 30

Page 46: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

Demo 40

Page 47: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

まずはデータバンデゖングを使ってModel-Viewから始めよう。

こうなったときはViewModelの出番

ViewとModelが直接バンドすると何かと都合が悪い

実装すべき場所がViewでもModelでもないコードがある

ViewModelに対する単体テストを書いてテストを自動化しよう。

Page 48: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

宣言的に記述されるバンデゖングはデバッグが困難

Visual Studio 2010に期待

規模が小さく単純なゕプリケーションでは割に合わない。

ソフトウェゕゕーキテクチャに「ただひとつの真の実装」は存在しない。

是非GrapeCityブースにお立ち寄りください。

Page 49: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

2008J Enterprise

Windowsフォーム、ASP.NETに加え、グリッド、チャート、スケジュール、レポート

の4つのWPFコンポーネントが新登場

http://www.grapecity.com/japan/c1/

Page 50: 【13 C 2】デベロッパーに贈る!M-V-VMパターンで造るWPFアプリケーション

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アプリケーション

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絶賛開発中!!