Download presentation
Presentation is loading. Please wait.
1
ViewModelからViewへのメッセージング手法
ダイアログ・アニメーション・画面遷移 2010/11/6 第60回codeseek勉強会 第2回日本C#ユーザー会勉強会 尾上
2
自己紹介 尾上 雅則(おのうえ まさのり) フリーランスだったり、会社があったり。 C#er VB.NET少々
もともとはサーバ側専門。たまにスマクラ Windows Forms 2009/6月ごろWPFに目覚め、パッケージをリリース。イベント駆動で開発した所、非常に苦労し、以後ほぼ一年間MVVMに夢中。 VB.NET少々 Silverlightってなんでしたっけ? Twitter Blog : the sea of fertility – Facebook :
3
ダイアログ・アニメーション・画面遷移の問題
なぜこれらは難しい?
4
どういう時に、ViewModelからViewを触りたくなる?
代表的なパターン ダイアログ アニメーション 画面遷移
5
ダイアログ ViewModelでMessageBox.Showする? ViewのコードビハインドからMessageBox.Showする
自動単体テストが・・・ ViewのコードビハインドからMessageBox.Showする コードビハインド・・・ FileDialog系(Save/Open)はどうしよう? 戻り値が必要なパターン
6
ダイアログ 実は2種類ある。 Viewが起点となって表示するダイアログ ViewModelが起点となって表示するダイアログ 実行確認系とか。
エラーダイアログ・終了前の保存確認とか
7
アニメーション ICommandの実行前後にアニメーションを挟みたい場合が多々ある。
コレクションの増減時にもアニメーションを挟みたい場面が多々ある。 View側で完結して欲しい処理 ViewModelには関わらせたくない 戻り値をViewModel側で処理したりする必要がない
8
画面遷移 実は最大の鬼門 パターンがたくさんある モーダルダイアログとしての遷移 新しいウィンドウを別に表示 Webページ的な遷移
ナビゲーション こいつはプログラミングモデルからして異なる。
9
共通する問題 いずれも、イベント駆動開発ではコードビハインドで処理してきたパターン BlendだけでUIを開発できないのも痛い
イベント駆動開発をしていると、コードビハインドはWPF/SLでは今までより増えるんです! Windows Formsより、WPFを選んだのは、UIの表現力が増したから! ASP.NETより、Silverlightを選ぶのは、WEBよりリッチなUIを構築したかったから! イベント駆動開発では、UIの見かけのみに関わるコードがコードビハインドに爆発! イベント発生順依存のコードを保守するのは大変 BlendだけでUIを開発できないのも痛い 自動単体テストはどうしましょう? UI Automation系での自動単体テストは結局いつも実現されてませんでした
10
みんなの努力 考えられてきた対処法もろもろ
11
みんなの努力 ViewModelからViewを操作したくなるシナリオでは世界中の人がいろんな手法を考えてきました。 代表的な手法
インターフェース Viewにコマンド Messenger
12
みんなの努力1 – インターフェース View ViewModel Interface Viewは特定のインターフェースを実装する
ViewModelはViewのインスタンスを、インターフェースの実装として持つ ViewModelはViewのコードビハインドに定義されたメソッドを、インターフェース経由で呼んでやるイメージ。 View ViewModel Interface
13
実装デモ プロジェクト: 1-InterfaceView
14
みんなの努力1 – インターフェース 長所 短所 一応疎結合は維持(たぶん。きっと。)
インターフェースを実装したViewのスタブオブジェクトを使えば、自動単体テストも可能。 短所 ViewModelにて、インターフェースをViewのインスタンスにキャストする事でViewを直接いぢり放題 きちんと管理しなければ、MVVMで開発している意味がなくなる 「きちんと管理」がそもそもできるのなら、そもそも設計パターンを使用する意味は・・・ コードビハインドがある。
15
ViewのXAMLで、ViewModelのプロパティにViewのコマンドを渡す
Viewが、コードビハインドにてICommandを実装する ViewのXAMLにて、ViewModelのプロパティにView側で定義されたICommandを渡してやる ViewModelは渡されたコマンドをExecute! ダイアログ表示ロジックなどはここに記述 View ViewModel コードビハインドで定義した ダイアログ表示用コマンド Viewで定義された コマンドを格納するプロパティ ViewのXAMLで、ViewModelのプロパティにViewのコマンドを渡す ViewModelは、渡されたコマンドを処理の中で自由に実行すれば良い。Interfaceの時と同じことを、ViewModelがViewのインスタンスを持つことなく実現している
16
実装デモ プロジェクト:2-ReverseCommand
17
みんなの努力2 – Viewにコマンド 長所 短所 バインディング機構だけで疎結合を実現しているのは素敵 単体テスト問題なし
コードビハインドがある ViewModel側がコマンドで乱雑になる 戻り値を受け取るのが大変
18
Viewがメッセージに対応するアクションを終えた後に実行される
みんなの努力3 – Messenger MVVM Light Toolkit Messengerというアプローチ ViewModelは、Viewに何らかのアクションを起こして欲しいタイミングでメッセージ(実体はイベント)を発信する。 ViewModel コールバックは Viewがメッセージに対応するアクションを終えた後に実行される
19
! イベントの解除などは、補助ライブラリ側で責任を持つ必要がある
みんなの努力3 – Messenger Viewはイベントを監視し、送られてきたメッセージに対応するアクションを実装する Viewの コードビハインド ! イベントの解除などは、補助ライブラリ側で責任を持つ必要がある
20
実装デモ プロジェクト:3-SimpleMessenger MVVM Light Toolkitを使って実装しました!
21
みんなの努力3 – Messenger 長所 短所 一応疎結合は維持(たぶん。きっと。) 単体テスト問題なし 受け入れられている
最近ではWindows Phone 7 のサンプルが良くMVVM Light Toolkitを使用して作られていた 短所 乱用しやすい 使ってみるとわかるが、ただのイベントの仕組みをラップしただけの仕組みのため、「きちんと管理」しないとMVVMを使う意味が・・。 「何も考えずに使うと」コードビハインドがある。
22
みんなの努力 – 共通した問題 コードビハインドがある 結局管理が難しい やっぱり微妙にクールじゃない BlendだけでViewが作れない
「きちんと管理」しないといけない=略 やっぱり微妙にクールじゃない
23
コードビハインドの抹殺 XAMLで書けない部分を、C#で書く。 でもそれはコードビハインドに書くわけではないのです。
24
コードビハインドの抹殺 - ビヘイビア・トリガー・アクション
ビヘイビア・トリガー・アクションを用いる事で、コードビハインドの抹殺が可能! ビヘイビア なんらからのイベント・ステートに基づいて、オブジェクトの状態を遷移させるのが主な役割 トリガー&アクション 任意のトリガーを起点として、任意のアクションを実行させられる。 (インフラが整っていれば)C#どころか、XAMLを手で一行も書かなくてもBlendのGUIで設定可能!
25
コードビハインドの抹殺 – ビヘイビア ビヘイビアとは、添付プロパティの仕組みを使って、オブジェクト自体が持たない状態と動作を、オブジェクトの外部から追加定義するもの。
26
コードビハインド抹殺 – ビヘイビア 実はビヘイビアと言われるものは2種類ある .NET Frameworkだけで作成できるビヘイビア
通称 添付ビヘイビア(Attached Behavior) 実装に時間がかかる Blend SDK 付属アセンブリを使用するビヘイビア ただビヘイビアと呼称 Blend SDKアセンブリ = System.Windows.Interactivity.dll 基底クラスが定義されていて、実装が楽。 System.Windows.Interactivity.dllにあたるものを自前実装する事もできるが、今後の標準化の方向などを考えると無駄かと。
27
実装デモ プロジェクト:4-SimpleBehaviors @okazuki さんのブログの素敵なサンプルをぱくらせていただきました
28
コードビハインドの抹殺 – トリガー&アクション
Trigger 言葉通り。後述するアクションのトリガーとなる Action 任意のトリガーによって起動されるアクション Blend 定義済Trigger & Action EventTrigger ChangePropertyAction DataTrigger KeyTrigger GotoStateAction PropertyChangedTrigger InvokeCommandAction StoryboardCompletedTrigger PlaySoundAction TimerTrigger LaunchUriOrFileAction
29
実装デモ プロジェクト:SampleTriggerAndAction
30
コードビハインドの抹殺 ビヘイビア & トリガーとアクションの使用はBlend SDKが前提
Blend SDKは、Expression Blendを持っていなくても単体で導入が可能! .NET Frameworkだけで使おうとすると EventTrigger以外のトリガーはスタイルやテンプレート以外では使えない トリガーもアクションも独自定義できない 基底クラスがinternal コンストラクタ(TriggerBase/TriggerAction) ビヘイビアの実装が非常に大変
31
Blend SDK Blend SDKを使うと.NET Frameworkだけでは不可能な、トリガー&アクションの独自定義が可能
BlendでUIの開発を行っていると、標準で利用可能 Blend SDKのライブラリは明示的にプロジェクトで参照しなくても、Blendでプロジェクトを読み込むだけで勝手に参照が追加される。 Blend SDK を使用しないMVVMなど個人的には絵空事。
32
ビヘイビア・トリガー・アクションで出来る事
Viewが起点となる動作や、ViewModelのプロパティの変化が起点となる動作ならば、結論からいえば何でもできます UI開発者はBlend上で、一切のコードを書かず(XAML含め)ビヘイビア・トリガー・アクションの引数を指定可能。
33
ビヘイビア・トリガー・アクションで出来る事
なんでもできる、けど、だからこそ・・・ 開発者みんなが自由に作ったらやっぱり大変な事に・・。 ビヘイビア・トリガー・アクションは定義済のものとしてインフラに組み込んでしまうべき。 都合の良い事に、ビヘイビア・トリガー・アクションはビジネスロジックのドメインと結合しにくい つまり、再利用が容易 ビヘイビア・トリガー・アクションは画面ごとに定義が必要なものではありません! Model呼び出しを伴わない様な処理はすべて処理できます。
34
コードビハインドの抹殺 – まとめ ビヘイビア・トリガー・アクションを使用する事で、Model呼び出しを伴わないような処理は全てコードビハインドを使わずに処理できる。 ViewModelのプロパティの変化を監視して、Viewを遷移させることなども可能。 Blend SDK使用が前提 しかし戻り値を返せないため、ViewModelを介してModelと連携するような処理は苦手・・・
35
ViewModelと連携する処理 ViewModelを介して、Modelと連携するような処理はどうするか?
36
Pattern & Practice Prismの採用方式です!
ViewModel起点アクションの処理 MVVM Light ToolkitのMessengerを思い出してください! Messengerがコードビハインドを使用するのは、メッセージに対応するアクションを記述する時だったはず もしメッセージに対応するアクションが、全てビヘイビア・アクションに移動すると・・ Viewの コードビハインド Pattern & Practice Prismの採用方式です!
37
実装デモ プロジェクト:MessagingAndBehaviors
Pattern & Practice Prismが採用している手法なのでPrismで実装してみました。
38
Messenger And Behaviors
すいません。パターン名はオレオレです。 ViewModelからMessageを送信(イベント発行)するコードはほぼ一緒 Messenger (MVVM Light Toolkit) InteractionRequest (Prism)
39
Messenger And Behaviors
しかしメッセージに対応するアクションはPrismではXAML(トリガー & アクション)で書きます。 MVVM Lightの例ではコードビハインドに書いていました。 Messenger (MVVM Light Toolkit) TriggerとTriggerActionによる処理(Prism)
40
Messenger And Behaviors
Messageに対応するアクションをTriggerActionに移動する事でもう一つ利点が生まれました ViewModelは純粋な意味でメッセージを発信し、Viewはメッセージに対応する好きな実装をGUI(Blend)で選ぶ事が出来ます! InteractionRequestTrigger ChangePropertyAction ダイアログを表示するアクション GotoStateAction 好きなActionを選べます InvokeCommandAction バルーンを表示するアクション
41
Messenger And Behaviors
今までのパターンのすべての長所を備え、かつ短所が少ない。 現在・今後も主流となるように思えます! Pattern & Practice Prismも採用 これが最大の根拠 MVVM Light Toolkitも、実はこの形を意識した実装がされています しかし同時に、コードビハインドも使用できるよう設計されている Cinch / Caliburnなどの他のメジャーなMVVMライブラリも採用しています 現在のPrismは不完全なので注意が必要
42
アニメーション・ダイアログ・画面遷移ではどのパターンを使う?
実際の所、パターンの使い分け
43
ダイアログはどうなる? View起点ダイアログの場合 ViewModel起点ダイアログの場合
トリガー&トリガーアクションを用いる事で、全てコードビハインドなしの解決が可能 ViewModel起点ダイアログの場合 エラーダイアログや対応確認ダイアログの場合 ビヘイビア・トリガー・アクション用にいちいちプロパティを用意する? ビヘイビア・トリガー・アクションだけでは、まだまだ強引な実装 だからこそ、Messenger And Behavior
44
実装デモ プロジェクト:7-DialogSample
45
アニメーションはどうなる? XAMLのみで完結できるアニメーションとビヘイビア、トリガー、アクションの相性は抜群
コードビハインドなしで、アニメーションを処理の合間に挟み込める
46
実装デモ プロジェクト:8-AnimationSample
47
画面遷移はどうなる 基本的にはMessenger And Behaviorを使います。 実はTODOです.
しかし実際に表示するViewのクラスは、 VMが指示するんでしょうか? メッセージを受け取ったViewが指定するんでしょうか? とりえあずダイアログと同じように実装は可能です. Messageの中に、新規画面のViewModelを含める事にはなるでしょう
48
MVVMでの実装指針 悩ましい所はどんな基準で実装する? まとめ。
49
MVVMでの実装に悩む時 まずは問題となる機能が、表示のみの機能なのか、Model呼び出しに影響を与える機能なのかを考える 表示のみの機能
例) アニメーション 実行通知ダイアログなど → Blendだけで構築できるのが望ましい Model呼び出しに影響を与えうる機能 FileDialo系などの、戻り値をビジネスロジックで処理する必要のあるダイアログ 画面遷移など →ViewModel経由、Modelとの連携が不可欠
50
表示のみの機能の実装指針 ビヘイビア・トリガー・アクションで解決する インフラ(ビヘイビア・トリガー・アクション)が整っていれば・・・
典型的なパターンを一度インフラとして実装してしまえば、新たにトリガー・アクションを実装する必要のある場合などほとんどない ビヘイビア・トリガー・アクションは基本的にビジネスロジックのドメインと非結合なため、インフラとして全社単位・あるいはフレームワーク単位での管理が容易 インフラ(ビヘイビア・トリガー・アクション)が整っていれば・・・ BlendだけでUI(View)の開発をする事が可能になる コードを触る必要がなくなる!
51
Model呼び出しに影響を与えうる機能の実装指針
Messenger And Behaviorsで解決する 現在あるパターンの中で最も短所が少なく、長所が多い方法 こちらもインフラ化しやすい インフラが整っていれば・・・ View側は、ViewModelから発されたメッセージに応じて自由な表現をBlendだけで実現できる
52
MVVMはマゾイとかまだ早いとか言われます
53
MVVMでの実装は面倒(マゾい)? DelegateCommmandやRelayCommand、ビヘイビア・トリガー・アクションはビジネスロジックのドメインに結合していません。 インフラ化が容易という事。標準ライブラリで採用されれば、まったく面倒ではなくなる。 Blendの使用が前提ならば、むしろイベント駆動開発よりはるかに楽です!
54
MVVMでの実装は面倒(マゾい)? ViewModelの記述が冗長? なによりもBlend使わなきゃ、WPF/SLの存在そのものがマゾい
ViewModelを自動生成させるために、Modelにすべてのビジネスロジックを載せましょう。 単純なデータ型のModel×。 詳しくは伊藤さんのセッションで! なによりもBlend使わなきゃ、WPF/SLの存在そのものがマゾい
55
MVVMは業務ではまだ早い? はい。インフラが整備・統一されていない現状では業務に採用するにはまだ早いです。
DelegateCommandとRelayCommandすら統一されていない。 機能的には同じなのに。 今後はPrismに合わせていくのが無難かも。 Message And Behaviorsは各種メジャーMVVM補助ライブラリではほぼ同じ形で実装されています しかし統一されていないのです
56
私見 MVVMの将来 私見ではMVVMはASP.NET MVCをWPF/SLの世界に持ってこようとしたもの。
でもWEBシステムそのもののシンプルなアーキテクチャ上の制約がWPF/SLにはない。 だからそのまま持ってこれなかった。 Pattern & Practice PrismはMVVMインフラにもなろうとしている。 将来的には標準ライブラリに取り込まれるのでは? 既存スキル・規模との兼ね合いを考えると、ASP.NETとASP.NET MVCみたいに、WPF(SL)とWPF(SL) MVVMみたいにテンプレートが別れていくのでは?
57
ご清聴有難うございました!
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.