Download free for 30 days
Sign in
Upload
Language (EN)
Support
Business
Mobile
Social Media
Marketing
Technology
Art & Photos
Career
Design
Education
Presentations & Public Speaking
Government & Nonprofit
Healthcare
Internet
Law
Leadership & Management
Automotive
Engineering
Software
Recruiting & HR
Retail
Sales
Services
Science
Small Business & Entrepreneurship
Food
Environment
Economy & Finance
Data & Analytics
Investor Relations
Sports
Spiritual
News & Politics
Travel
Self Improvement
Real Estate
Entertainment & Humor
Health & Medicine
Devices & Hardware
Lifestyle
Change Language
Language
English
Español
Português
Français
Deutsche
Cancel
Save
Submit search
EN
Uploaded by
伸男 伊藤
PPTX, PDF
1,967 views
T119_5年間の試行錯誤で進化したMVPVMパターン
わんくま同盟 東京勉強会 #119 www.wankuma.com/seminar/20191214tokyo119/ で喋ったMVPVMパターンの話 アニメーションを多用しているのでダウンロード推奨
Engineering
◦
Read more
0
Save
Share
Embed
Embed presentation
Download
Download to read offline
1
/ 48
2
/ 48
3
/ 48
Most read
4
/ 48
Most read
5
/ 48
6
/ 48
Most read
7
/ 48
8
/ 48
9
/ 48
10
/ 48
11
/ 48
12
/ 48
13
/ 48
14
/ 48
15
/ 48
16
/ 48
17
/ 48
18
/ 48
19
/ 48
20
/ 48
21
/ 48
22
/ 48
23
/ 48
24
/ 48
25
/ 48
26
/ 48
27
/ 48
28
/ 48
29
/ 48
30
/ 48
31
/ 48
32
/ 48
33
/ 48
34
/ 48
35
/ 48
36
/ 48
37
/ 48
38
/ 48
39
/ 48
40
/ 48
41
/ 48
42
/ 48
43
/ 48
44
/ 48
45
/ 48
46
/ 48
47
/ 48
48
/ 48
More Related Content
PPTX
Mvpvm pattern
by
Mami Shiino
PDF
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
by
日本マイクロソフト株式会社
PDF
UniTask入門
by
torisoup
PDF
[JJUG CCC 2021 Spring]Eclipse ユーザのための VSCode のススメ
by
Satoshi Takami
PDF
ドメイン駆動設計のための Spring の上手な使い方
by
増田 亨
PDF
Dockerからcontainerdへの移行
by
Kohei Tokunaga
PPTX
async/await のしくみ
by
信之 岩永
PDF
UniRx の1歩目
by
infinite_loop
Mvpvm pattern
by
Mami Shiino
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
by
日本マイクロソフト株式会社
UniTask入門
by
torisoup
[JJUG CCC 2021 Spring]Eclipse ユーザのための VSCode のススメ
by
Satoshi Takami
ドメイン駆動設計のための Spring の上手な使い方
by
増田 亨
Dockerからcontainerdへの移行
by
Kohei Tokunaga
async/await のしくみ
by
信之 岩永
UniRx の1歩目
by
infinite_loop
What's hot
PDF
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
by
Yoshifumi Kawai
PPTX
GitLab CI/CD パイプライン
by
Tetsurou Yano
PDF
Observableで非同期処理
by
torisoup
PDF
ソーシャルゲーム案件におけるDB分割のPHP実装
by
infinite_loop
PDF
インタフェース完全に理解した
by
torisoup
PDF
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
by
日本マイクロソフト株式会社
PDF
コンテナ未経験新人が学ぶコンテナ技術入門
by
Kohei Tokunaga
PDF
分散システムの限界について知ろう
by
Shingo Omura
PDF
UniRx完全に理解した
by
torisoup
PDF
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
by
UnityTechnologiesJapan002
PDF
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
by
Google Cloud Platform - Japan
PPTX
BuildKitによる高速でセキュアなイメージビルド
by
Akihiro Suda
PPTX
Docker超入門
by
VirtualTech Japan Inc.
PDF
オンラインゲームの仕組みと工夫
by
Yuta Imai
PPTX
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
by
Unity Technologies Japan K.K.
PPTX
C#とILとネイティブと
by
信之 岩永
PDF
Fluentdのお勧めシステム構成パターン
by
Kentaro Yoshida
PDF
WPF開発での陥りやすい罠
by
Sho Okada
PPTX
大規模ゲーム開発における build 高速化と安定化
by
DeNA
PDF
ドキュメントを作りたくなってしまう魔法のツール「Sphinx」
by
Yoshiki Shibukawa
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
by
Yoshifumi Kawai
GitLab CI/CD パイプライン
by
Tetsurou Yano
Observableで非同期処理
by
torisoup
ソーシャルゲーム案件におけるDB分割のPHP実装
by
infinite_loop
インタフェース完全に理解した
by
torisoup
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
by
日本マイクロソフト株式会社
コンテナ未経験新人が学ぶコンテナ技術入門
by
Kohei Tokunaga
分散システムの限界について知ろう
by
Shingo Omura
UniRx完全に理解した
by
torisoup
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
by
UnityTechnologiesJapan002
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
by
Google Cloud Platform - Japan
BuildKitによる高速でセキュアなイメージビルド
by
Akihiro Suda
Docker超入門
by
VirtualTech Japan Inc.
オンラインゲームの仕組みと工夫
by
Yuta Imai
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
by
Unity Technologies Japan K.K.
C#とILとネイティブと
by
信之 岩永
Fluentdのお勧めシステム構成パターン
by
Kentaro Yoshida
WPF開発での陥りやすい罠
by
Sho Okada
大規模ゲーム開発における build 高速化と安定化
by
DeNA
ドキュメントを作りたくなってしまう魔法のツール「Sphinx」
by
Yoshiki Shibukawa
Similar to T119_5年間の試行錯誤で進化したMVPVMパターン
PDF
RIAアーキテクチャー研究会 第3回 セッション4 Mvpvm pattern
by
Mami Shiino
PPTX
T90 きっと怖くないmvvm & mvpvm
by
伸男 伊藤
KEY
塹壕よりLivetとMVVM
by
Hiroshi Maekawa
PDF
これからはじめる XAML - WPF プログラミング
by
インフラジスティックス・ジャパン株式会社
PDF
僕がやったXaml戦略
by
Hiroyuki Mori
PPTX
Xamarin.formsでのmvvm利用のコツ
by
Masuda Tomoaki
PPTX
MVVM入門
by
Kazutoshi Urabe
PDF
WPFことはじめ
by
Hiroshi Maekawa
PDF
//publish/ MSPTutorial 応用編
by
Yuki Igarashi
PPTX
Msを16倍出し抜くwpf開発1回目
by
cct-inc
PPTX
いまさら学ぶMVVMパターン
by
Yuta Matsumura
PPTX
Visual Studio による開発環境・プログラミングの進化
by
Fujio Kojima
PPTX
Windows ストア アプリの上手な作り方
by
一希 大田
PPTX
Building Silverlight Large Scale Application Using MVVM
by
Shotaro Suzuki
PDF
WPF/Silverlight視点で視るMetroスタイルのXAML
by
Yuya Yamaki
PPTX
Uwpでみるxaml入門第二回
by
Makoto Nishimura
PDF
Introduction for Browser Side MVC
by
Ryunosuke SATO
PPTX
MVVM開発をさらに加速させる ノンコーディングUI開発
by
c-mitsuba
PPTX
Visual studio 2013 Overview
by
一希 大田
PDF
わんくま同盟名古屋勉強会18回目 ASP.NET MVC3を利用したHTML5な画面開発~クラウドも有るよ!~
by
normalian
RIAアーキテクチャー研究会 第3回 セッション4 Mvpvm pattern
by
Mami Shiino
T90 きっと怖くないmvvm & mvpvm
by
伸男 伊藤
塹壕よりLivetとMVVM
by
Hiroshi Maekawa
これからはじめる XAML - WPF プログラミング
by
インフラジスティックス・ジャパン株式会社
僕がやったXaml戦略
by
Hiroyuki Mori
Xamarin.formsでのmvvm利用のコツ
by
Masuda Tomoaki
MVVM入門
by
Kazutoshi Urabe
WPFことはじめ
by
Hiroshi Maekawa
//publish/ MSPTutorial 応用編
by
Yuki Igarashi
Msを16倍出し抜くwpf開発1回目
by
cct-inc
いまさら学ぶMVVMパターン
by
Yuta Matsumura
Visual Studio による開発環境・プログラミングの進化
by
Fujio Kojima
Windows ストア アプリの上手な作り方
by
一希 大田
Building Silverlight Large Scale Application Using MVVM
by
Shotaro Suzuki
WPF/Silverlight視点で視るMetroスタイルのXAML
by
Yuya Yamaki
Uwpでみるxaml入門第二回
by
Makoto Nishimura
Introduction for Browser Side MVC
by
Ryunosuke SATO
MVVM開発をさらに加速させる ノンコーディングUI開発
by
c-mitsuba
Visual studio 2013 Overview
by
一希 大田
わんくま同盟名古屋勉強会18回目 ASP.NET MVC3を利用したHTML5な画面開発~クラウドも有るよ!~
by
normalian
More from 伸男 伊藤
PPTX
T93 com入門
by
伸男 伊藤
PPTX
没セッション 知識ゼロから学んだソフトウェアテスト
by
伸男 伊藤
PPTX
わんくまT84 kinect深度情報処理入門
by
伸男 伊藤
PPTX
わんくまT78 mfcを始めようとしてみた
by
伸男 伊藤
PPTX
Kinect深度情報処理入門
by
伸男 伊藤
PPTX
T69 c++cli ネイティブライブラリラッピング入門
by
伸男 伊藤
T93 com入門
by
伸男 伊藤
没セッション 知識ゼロから学んだソフトウェアテスト
by
伸男 伊藤
わんくまT84 kinect深度情報処理入門
by
伸男 伊藤
わんくまT78 mfcを始めようとしてみた
by
伸男 伊藤
Kinect深度情報処理入門
by
伸男 伊藤
T69 c++cli ネイティブライブラリラッピング入門
by
伸男 伊藤
T119_5年間の試行錯誤で進化したMVPVMパターン
1.
わんくま同盟 東京勉強会 #119 5年間の試行錯誤で進化した MVPVMパターン 暁
紫電 @akatukisiden
2.
わんくま同盟 東京勉強会 #119 自己紹介 •
本名:伊藤 伸男 • フリーランス プログラマー • スキル – C# – C++ – C++/CLI – JavaScript – Salesforce
3.
わんくま同盟 東京勉強会 #119 はじめに •
2014/06/07 東京勉強会 #90 「きっと怖くないMVVM&MVPVM」から5年 • 仕事でWPFの経験を積みながら • 何かか作りたいアプリが出来た時の為に MVPVMフレームワークだけでも作っておこうと思って 作り始めるも、なかなかうまくいかなかったり、他の勉強を 始めたりで中断 という事を繰り返してきました • その試行錯誤の成果がまとまりつつあるので 紹介したいと思います。
4.
わんくま同盟 東京勉強会 #119 MVPVMとは •
Model-View-Presenter-ViewModel • MVVMパターンにMVPパターンを合体させた もの • MVVMでは,ViewとViewModelに分散してい た画面遷移に関する処理をPresenter一つに まとめることができるため処理が追いやすい
5.
わんくま同盟 東京勉強会 #119 Model •
ビジネスロジック • View,Presenter,ViewModel以外の部分 View • ユーザーインターフェース • UIへの出力とUIからの入力を担当する。 • FrameworkElementの派生クラス • XAMLの記述+対応する partial class
6.
わんくま同盟 東京勉強会 #119 ViewModel •
Viewの情報を保持(データバインド) • Viewから受け取った入力やコマンドをPresenterに渡す Presenter • View,ViewModelを保持、その接続を管理する • ViewModelから受け取った入力やコマンドを処理し Modelを呼び出す。 • ViewModelのプロパティを通してViewを変更する。 • ナビゲーション・画面遷移の管理
7.
わんくま同盟 東京勉強会 #119 参照関係 Model ViewModel View Presenter (DataContext)
8.
わんくま同盟 東京勉強会 #119 MVPVMパターン Model ViewModel View Presenter ナビゲーション コマンド等 データバインド 呼び出し コマンドの 内容はPに実装 イベント
9.
わんくま同盟 東京勉強会 #119 画面遷移時にどちらのコントロールを使うか •
ContentControl ひとつのコントロールを表示するだけ シンプルで扱いやすい • Frame,NavigationWindow (UWPではFrameのみ) ナビゲーション前・後イベント 履歴(戻る、進む) Pageインスタンスのキャッシュ等 画面遷移に関する機能を持つ 正直、履歴機能とかあまり使わないので ContentControlで良い気がする
10.
わんくま同盟 東京勉強会 #119 UWPアプリでは Frameの使用がほぼ必須 画面遷移時のアニメーションサポート機能が付いているため
11.
わんくま同盟 東京勉強会 #119 {x:Bind}マークアップ •
UWPで追加されたバインド方法 • {Binding}より高速 • PathのルートはDataContext ではなく、Page • コンパイル時にバインド式が検証されコードが生成される (obj/*.g.cs に生成) • バインド式が間違っていたらコンパイルエラーが発生
12.
わんくま同盟 東京勉強会 #119 {x:Bind}マークアップ •
Pageを表すクラスからバインディング ソース(ViewModel) クラスを公開する必要がある public sealed partial class Page1 : Page { public Page1() { this.InitializeComponent(); this.ViewModel = new Page1ViewModel(); } public Page1ViewModel ViewModel { get; set; } } <Page x:Class=“Page1" ... > <TextBlock Text="{x:Bind Path=ViewModel.Text, Mode=OneWay}" ... /> </Page>
13.
わんくま同盟 東京勉強会 #119 obj/Page1.g.cs
({x:bind}) partial class Page1 :… { private static class XamlBindingSetters { public static void Set_Windows_UI_Xaml_Controls_TextBlock_Text (TextBlock obj, String value, string targetNullValue) { if (value == null && targetNullValue != null) {value = targetNullValue;} obj.Text = value ?? String.Empty; } }; private class Page1_obj1_Bindings : … { public void Update() { this.Update_(this.dataRoot, NOT_PHASED); this.initialized = true; } private void Update_(Views.Page1 obj, int phase) { if (obj != null) { if ((phase & (NOT_PHASED | (1 << 0))) != 0) {this.Update_ViewModel(obj.ViewModel, phase);} } } private void Update_ViewModel(Page1ViewModel obj, int phase) { if (obj != null) { if ((phase & (NOT_PHASED | (1 << 0))) != 0) {this.Update_ViewModel_Text(obj.Text, phase);} } } private void Update_ViewModel_Text(System.String obj, int phase) { if ((phase & ((1 << 0) | NOT_PHASED )) != 0) { if (!isobj2TextDisabled) { XamlBindingSetters. Set_Windows_UI_Xaml_Controls_TextBlock_Text( this.obj2, obj, null); } } } } }
14.
わんくま同盟 東京勉強会 #119 obj/Page1.g.cs
({Binding}) partial class Page1 :… { private class Page1_obj1_Bindings : … { public void Update() { this.Update_(this.dataRoot, NOT_PHASED); this.initialized = true; } private void Update_(Views.Page1 obj, int phase) { if (obj != null) { } } } }
15.
わんくま同盟 東京勉強会 #119 {x:Bind}とイベント、関数 •
コマンドだけでなく、イベント(と関数)のバインドが可能 • <Button Click="{x:Bind ViewModel.OnClick}" /> • RoutedEventも使用可 <Button Click="{x:Bind ViewModel.Clicked}" /> • Bind構文内で関数を呼び出して Converterのように使うことができる。 <TextBlock Text=“{x:Bind ViewModel.ConvertFunc(ViewModel.Text) }” />
16.
わんくま同盟 東京勉強会 #119 便利そうだけどこれって 厳密に言うと密結合では?
17.
わんくま同盟 東京勉強会 #119 気にしないことにしよう!
18.
わんくま同盟 東京勉強会 #119 最終的にこんな感じに public
sealed partial class Page1 : Page { public Page1ViewModel ViewModel { set { this.DataContext = value; } get { return this.DataContext as Page1ViewModel; } } }
19.
わんくま同盟 東京勉強会 #119 クラス図(UWP) Frame PresenterBase Page PresenterBase Parent PresenterBaseCore ChildPage PresenterBaseCore PresenterBase PresenterBaseCore 〇〇FramePresenter 〇〇Page Presenter Window PresenterBase 〇〇Window Presenter 通常のWindowとは 別物 View,ViewMode 非ジェネリック View,ViewMode ジェネリック
20.
わんくま同盟 東京勉強会 #119 クラス図(WPF) Frame PresenterBase NavigationWindow PresenterBase Page PresenterBase Parent PresenterBaseCore ChildPage PresenterBaseCore PresenterBase PresenterBaseCore Window PresenterBase 〇〇FramePresenter 〇〇NavigationWindow Presenter 〇〇Page Presenter 〇〇Window Presenter Frame,NavigationWindowで できる限り実装を共有
21.
わんくま同盟 東京勉強会 #119 サンプル •
UWP • Frame(NavigationWindow)で ボタンを押すとPage1からPage2,Page2から Page1へと遷移する • https://github.com/akatukisiden/MVPVM
22.
わんくま同盟 東京勉強会 #119 事前起動 •
OS がバックグラウンドでプロセスを起動する ことで、使用開始時の読み込み時間を短縮 パフォーマンスを向上させる
23.
わんくま同盟 東京勉強会 #119 アプリケーションクラス public
sealed partial class App : Application { public WindowPresenter WindowPresenter { get; set; } public App() { // 事前起動有効化 CoreApplication.EnablePrelaunch(true); this.InitializeComponent(); this.EnteredBackground += App_EnteredBackground; this.LeavingBackground += App_LeavingBackground; this.Resuming += App_Resuming; this.Suspending += App_Suspending; this.UnhandledException += App_UnhandledException; WindowPresenter = new WindowPresenter(); }
24.
わんくま同盟 東京勉強会 #119 protected
override void OnLaunched(LaunchActivatedEventArgs e) { Frame rootFrame = Window.Current.Content as Frame; if (rootFrame == null) { WindowPresenter.Initialize(); } if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) { /* 以前中断したアプリケーションから状態を読み込みます*/ } if (e.PrelaunchActivated == false) { if (rootFrame.Content == null) { WindowPresenter.Navigate(typeof(Page1)); } WindowPresenter.Activate(); } else { /* 事前起動 */ } } 初期化処理 事前起動済みの時は本起動時 は実行しない 本起動時のみ実行 画面を表示する
25.
わんくま同盟 東京勉強会 #119 事前起動のテスト方法 •
デバッグ>その他のデバッグターゲット>ユニバーサルWindowsアプリ事前起動のデバッグ • 事前起動後の本起動のデバッグはスタートメニューなどからの起動で可能
26.
わんくま同盟 東京勉強会 #119 WindowPresenterBase.cs public
abstract class WindowPresenterBase { public WindowPresenterBase() { } public Window Window { set; get; } public virtual void Initialize() { if (Window == null) { Window = Window.Current; Window.Activated += Window_Activated; Window.Closed += Window_Closed; Window.SizeChanged += Window_SizeChanged; Window.VisibilityChanged += Window_VisibilityChanged; } } public virtual void Cleanup() { Window.Activated -= Window_Activated; Window.Closed -= Window_Closed; Window.SizeChanged -= Window_SizeChanged; Window.VisibilityChanged -= Window_VisibilityChanged; Window = null; }
27.
わんくま同盟 東京勉強会 #119 WindowPresenter.cs public
class WindowPresenter :WindowPresenterBase { public RootFramePresenter RootFramePresenter { get; set; } public WindowPresenter() { RootFramePresenter = new RootFramePresenter(); } public override void Initialize() { base.Initialize(); // ナビゲーション コンテキストとして動作するフレームを作成 var root = new Frame(); this.Window.Content = root; this.RootFramePresenter.View = root; this.RootFramePresenter.Initialize(); } public bool Navigate(Type key) { return RootFramePresenter.Navigate(key);} public override void Cleanup() { base.Cleanup(); }
28.
わんくま同盟 東京勉強会 #119 Frame.Navigate(Type,
object,NavigationTransitionInfo) • 遷移先ページを指すType,パラメータ、ナビゲーション時のア ニメの種類を引数に取る • WPFではアニメの種類は無しでTypeの代わりにUriを用いる – Pageのインスタンスを使うオーバーロードもあるが、ナビ ゲーションのキャンセル時等は、 作成したインスタンスが使われないままになるので個人的 には非推奨 • Navigating(キャンセル可),Navigatedイベントが呼 び出される
29.
わんくま同盟 東京勉強会 #119 Frame.Navigate(Type,
object,NavigationTransitionInfo) • Navigatingイベントでキャンセルされた場合 NavigationStoppedイベントが発火 – WPFではキャンセル時には発生しないがStopLoading() を呼び出すことで手動で発生させることができる – ナビゲーション中に別のナビゲーションを開始しても 発生するらしいが詳しい条件は不明 • Navigatedイベント中に例外がが発生すると NavigationFailedイベントが発火 – WPFだとIOExceptionじゃないといけないので注意
30.
わんくま同盟 東京勉強会 #119 RootFramePresenter.cs public
class RootFramePresenter: FramePresenterBase<Frame,EmptyViewModel> { public RootFramePresenter() { AddChild(typeof(Page1), new Page1Presenter()); AddChild(typeof(Page2), new Page2Presenter()); } public override void Initialize() { base.Initialize(); this.IsNavigationStackEnabled = true; } public override void Cleanup() { base.Cleanup(); } } 最初に、Presenterのインスタンスを作成 Viewの型とセットで登録
31.
わんくま同盟 東京勉強会 #119 Presenterの作成タイミング •
Presenter,とViewModelは最初にまとめて作成して おく。 • Viewのインスタンスが作られるタイミングで Presenterを作ろうとしたこともあるのだが、 気が付いたらFrameのもつ履歴やインスタンス キャッシュの機能をPresenterに再実装しようとして しまったり、 Viewの型に応じたPresenterを作成するしくみが必 要になったりしたため、 これなら最初に作成しておいた方が楽だと判断した
32.
わんくま同盟 東京勉強会 #119 FramePresenterBase public
abstract class FramePresenterBase<TView, TViewModel> : ParentPresenterBaseCore where TView : Windows.UI.Xaml.Controls.Frame, new() where TViewModel : ViewModelBase, new() { public FramePresenterBase() { ViewModel = new TViewModel(); } public bool IsNavigationStackEnabled { get { return View.IsNavigationStackEnabled; } set { View.IsNavigationStackEnabled = value; } } public TView View { get { return this.ViewBase as TView; } set { this.ViewBase = value; } } public TViewModel ViewModel { get { return this.ViewModelBase as TViewModel; } set { this.ViewModelBase = value; } } ナビゲーション履歴を使うかどうか Viewの同名プロパティにアクセス 非ジェネリック基底クラス(Core)の プロパティをキャスト
33.
わんくま同盟 東京勉強会 #119 FramePresenterBase public
override void Initialize() { base.Initialize(); IsNavigationStackEnabled = false; View.Navigating += View_Navigating; View.Navigated += View_Navigated; View.NavigationFailed += View_NavigationFailed; View.NavigationStopped += View_NavigationStopped; } public override void Cleanup() { View.Navigating -= View_Navigating; View.Navigated -= View_Navigated; View.NavigationFailed -= View_NavigationFailed; View.NavigationStopped -= View_NavigationStopped; base.Cleanup(); }
34.
わんくま同盟 東京勉強会 #119 FramePresenterBase public
override bool Navigate (Type key, object extraData = null, NavigationTransitionInfo infoOrverride =null) { return View.Navigate(key, extraData, infoOrverride); } public override void GoForward() { View.GoForward(); } public override void GoBack(NavigationTransitionInfo infoOrverride = null) { View.GoBack(infoOrverride); } private void View_Navigated(object sender, NavigationEventArgs e) { View_NavigatedCore(sender, e); } } 画面遷移関係の関数 Frameの同名関数を呼び出し 通常の遷移,進む,戻る 遷移時のアニメーションの種類 ParentPresenterBaseCore の関数を呼び出し
35.
わんくま同盟 東京勉強会 #119 ParentPresenterBaseCore.cs public
abstract class ParentPresenterBaseCore : PresenterBaseCore { protected Dictionary<Type, ChildPagePresenterBaseCore> Children { get; private set; }; public void AddChild(Type key, ChildPagePresenterBaseCore child) { Children.Add(key, child); } public void RemoveChild(Type key) { Children.Remove(key); } 本体はDictionary 子Presenterの登録 子Presenterの解除
36.
わんくま同盟 東京勉強会 #119 ParentPresenterBaseCore.cs public
ParentPresenterBaseCore() { Children = new Dictionary<Type, ChildPagePresenterBaseCore>(); } public ChildPagePresenterBaseCore CurrentChild { get; internal set; }; public override void Initialize() { base.Initialize(); } public override void Cleanup() { if (CurrentChild != null) { CurrentChild.Cleanup(); CurrentChild = null; } base.Cleanup(); } 表示中の子(Page)Presenter
37.
わんくま同盟 東京勉強会 #119 ParentPresenterBaseCore.cs protected
void View_NavigationStopped(object sender, NavigationEventArgs e) { CurrentChild.InvokeOnNavigationStopped(e); } protected void View_Navigating(object sender, NavigatingCancelEventArgs e) { if (CurrentChild != null) { CurrentChild.InvokeOnNavigatingFrom(e); } } protected void View_NavigationFailed(object sender, NavigationFailedEventArgs e) { CurrentChild.InvokeOnNavigationFailed(e); } Internal 関数を通してイベントに対応するPagePresenterの関数を呼び出し
38.
わんくま同盟 東京勉強会 #119 ParentPresenterBaseCore.cs protected
internal void View_NavigatedCore(object sender, NavigationEventArgs e) { if (e != null) { if (CurrentChild != null) { CurrentChild.InvokeOnNavigatedFrom(e); CurrentChild.Cleanup(); CurrentChild = null; } Type key = e.Content.GetType(); var childPresenter = Children[key]; var element = e.Content as FrameworkElement; childPresenter.Parent = this; childPresenter.ViewBase = element; CurrentChild = childPresenter; childPresenter.Initialize(); childPresenter.InvokeOnNavigatedTo(e); } } 表示中のページの終了処理 遷移先Pageに対応したPagePresenterを取得 遷移先Presenterの初期化処理 internal関数を介して PagePresenter.OnNavigatedFrom(e) の呼び出し PagePresenter.OnNavigatedTo(e) の呼び出し
39.
わんくま同盟 東京勉強会 #119 •
UWPのPageには3つのオーバーライド用関数が存在 – OnNavigatedTo (Pageへ遷移してきたときに実行) – OnNavigatingFrom (Pageから遷移するときに実行,キャンセル可) – OnNavigatedFrom (Pageから遷移したときに実行) • MVPVMではできるだけViewにコードを書きたくないため同 名の関数をPagePresenterに用意して同じような感覚で使え るようにしている
40.
わんくま同盟 東京勉強会 #119 Page1Presenter public
class Page1Presenter : PagePresenterBase<Views.Page1, Page1ViewModel> { public override void Initialize() { base.Initialize(); ViewModel.ClickEvent += Click; this.ViewModel.Text = "Page1"; } public void Click(object sender, RoutedEventArgs args) { this.Parent.Navigate(typeof(Page2), null); } public override void Cleanup() { ViewModel.ClickEvent -= Click; base.Cleanup(); } x:bindで呼び出すイベント
41.
わんくま同盟 東京勉強会 #119 PagePresenterBase public
abstract class PagePresenterBase<TView, TViewModel> : ChildPagePresent erBaseCore where TView : Page, new() where TViewModel : ViewModelBase, new() { public PagePresenterBase() { ViewModel = new TViewModel(); } public TView View { get { return this.ViewBase as TView; } set { this.ViewBase = value; } } public TViewModel ViewModel { get { return this.ViewModelBase as TViewModel; } set { this.ViewModelBase = value; } }
42.
わんくま同盟 東京勉強会 #119 PagePresenterBase public
override void Initialize() { base.Initialize(); View.Loaded += OnPageLoaded; } protected virtual void OnPageLoaded(object sender, RoutedEventArgs e) {} public override void Cleanup() { View.Loaded -= OnPageLoaded; base.Cleanup(); } }
43.
わんくま同盟 東京勉強会 #119 ChildPresenterBaseCore public
abstract class ChildPagePresenterBaseCore : PresenterBaseCore { public ParentPresenterBaseCore Parent { get; set; } public override void Initialize() { base.Initialize(); } public override void Cleanup() { Parent = null; base.Cleanup(); } 親FramePresenter 参照外し
44.
わんくま同盟 東京勉強会 #119 ChildPresenterBaseCore internal
void InvokeOnNavigatedTo(NavigationEventArgs e) { OnNavigatedTo(e);} internal void InvokeOnNavigatingFrom(NavigatingCancelEventArgs e) { OnNavigatingFrom(e); } internal void InvokeOnNavigatedFrom(NavigationEventArgs e) { OnNavigatedFrom(e); } internal void InvokeOnNavigationStopped(NavigationEventArgs e) {OnNavigationStopped (e); } internal void InvokeOnNavigationFailed(NavigationFailedEventArgs e) { OnNavigationFailed(e); }
45.
わんくま同盟 東京勉強会 #119 ChildPresenterBaseCore protected
virtual void OnNavigatedTo(NavigationEventArgs e) { } protected virtual void OnNavigatingFrom(NavigatingCancelEventArgs e) {} protected virtual void OnNavigatedFrom(NavigationEventArgs e) {} protected virtual void OnNavigationFailed(NavigationFailedEventArgs e) {} protected virtual void OnNavigationStopped(NavigationEventArgs e) {} }
46.
わんくま同盟 東京勉強会 #119 PresenterBaseCore public
abstract class PresenterBaseCore { protected TaskScheduler UIThreadTaskScheduler { get; private set; } public bool IsEnable { get; private set; } internal FrameworkElement ViewBase { get; set; } internal ViewModelBase ViewModelBase { get; set; } public PresenterBaseCore() { this.IsEnable = false; } Presenterが有効かどうか Initialize()でtrue CleanUp()でfalse View,ViewModel 非ジェネリック基底クラス用
47.
わんくま同盟 東京勉強会 #119 PresenterBaseCore public
virtual void Initialize() { this.UIThreadTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); ViewBase.DataContext = ViewModelBase; IsEnable = true; } public virtual void Cleanup() { if (ViewBase != null) { ViewBase.DataContext = null; ViewBase = null; } IsEnable = false; } ViewとViewModelを接続 接続解除 Viewの参照外し 破壊ではなく解放 管理をViewフレームワークに 返すイメージ
48.
わんくま同盟 東京勉強会 #119 まとめ •
UWPでは画面遷移アニメーションがあるので ContentControlではなくてFrameを使う • Presenter,ViewModelは最初にまとめて作る • View(Page)の作成はできる限りフレームワー クに任せ、 使用後は参照を解除し 管理権をフレームワークに返すことでViewの 機能を最大限生かす
Download