xamarin.formsでのmvvm利用のコツ

38
Xamarin.Forms でで MVVM ででででで Microsoft MVP C# でで でで Moonmile Solutions

Upload: moonmile

Post on 22-Apr-2015

791 views

Category:

Software


0 download

DESCRIPTION

Xamarin.Forms の MVVM パターンの解説です。 MVVM の基礎と、Xmarin.Forms 特有の MVVM パターンを説明しています。

TRANSCRIPT

Page 1: Xamarin.formsでのmvvm利用のコツ

Xamarin.Forms でのMVVM 利用のコツ

Microsoft MVP C#

増田 智明Moonmile Solutions

Page 2: Xamarin.formsでのmvvm利用のコツ

自己紹介

増田 智明 [email protected]

執筆業&プログラマ C# による iOS, Android, Windows アプリケーション開発入門 逆引き大全 Visual C# 2013, Visual Basic 2013

逆引き大全 iPhone/iPad アプリ開発 作って覚える iPhone/iPad アプリ入門

Page 3: Xamarin.formsでのmvvm利用のコツ

アジェンダ

シンプルに MVVM の仕組みを知るMVVM の得意なところを知るXamarin.Forms 特有の MVVMMVVM の限界を知る

Page 4: Xamarin.formsでのmvvm利用のコツ

シンプルに MVVM の仕組みを理解必要な時にを必要なものだけを使う

Page 5: Xamarin.formsでのmvvm利用のコツ

シンプルな MVVM

View ViewModel Model

XAML DataGlue

ViewModel(Model)XAML

ViewModel にデータを含ませてしまうことが多い

シンプルに実装したいから

Page 6: Xamarin.formsでのmvvm利用のコツ

クラス分けする

View ViewModel Model

XAML ViewModelClass

Codebehind

*.cs

INotifyPropertyChangedICommand

Azure/Web API

etc

Page 7: Xamarin.formsでのmvvm利用のコツ

Binding の関係( Label )

XAML ViewModel+ModelClass

Codebehind

*.cs

<ContentPage> <Label Text="{Binding Name}"/>

public class MyItem : BindableBase { private string _Name; public string Name { get { return _Name; } set { this.SetProperty(ref this._Name, value); } }

var vm = new MyItem();this.BindingContext = vm;

Page 8: Xamarin.formsでのmvvm利用のコツ

Binding の関係( Label )

XAML ViewModel+ModelClass

Codebehind

*.cs

<ContentPage> <Label Text="{Binding Name}"/>

public class MyItem : BindableBase { private string _Name; public string Name { get { return _Name; } set { this.SetProperty(ref this._Name, value); } }

var vm = new MyItem();this.BindingContext = vm;

Page 9: Xamarin.formsでのmvvm利用のコツ

Binding の関係( ListView )

XAMLViewModel+Model

ClassCodebehin

d*.cs

<ListView> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout> <Label Text="{Binding Name}" />

public class MyItems : ObservableCollection<MyItem> {

var items = new MyItems();lv.ItemsSource = items;

public class MyItem : BindableBase { private string _Name; public string Name { get; set; } { get { return _Name; } set { this.SetProperty(ref this._Name, value); } }※ ただし、一度だけの表示であれば、

  INotifyPropertyChanged を実装する必要はない。

Page 10: Xamarin.formsでのmvvm利用のコツ

Binding の関係( ListView 複合)

XAML

ViewModel+ModelClassCodebehin

d*.cs

<ContentPage> <ListView ItemsSource="{Binding Items}"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout> <Label Text="{Binding Name}" />

public class MyItems : ObservableCollection<MyItem>{

var vm = new MyViewModel();this.BindingContext = vm;

public class MyItem : BindableBase{ private string _Name; public string Name { get; set; } { get { return _Name; } set { this.SetProperty(ref this._Name, value); } }

public class MyViewModel{ public MyItems Items { get; set; }

Page 11: Xamarin.formsでのmvvm利用のコツ

シーケンス図( ViewMode で変更)

XAML ViewModelCodebehin

d*.cs

Binding

INotifyPropertyChanged

Change

Display

Create

Page 12: Xamarin.formsでのmvvm利用のコツ

シーケンス図( View で変更)

XAML ViewModelCodebehin

d*.cs

Binding

Changed

Lookup

Changed

Create

Page 13: Xamarin.formsでのmvvm利用のコツ

Entry の入力を Label に反映するパターン

XAML ViewModelCodebehin

d*.cs

Changed

Changed

INotifyPropertyChanged

Change

Display

ユーザの入力を自動で View に反映させ

るトリック

Page 14: Xamarin.formsでのmvvm利用のコツ

ICommand の関係

XAML

ViewModel+ModelClass

Codebehind

*.cs

<ContentPage> <Button Command="{Binding UpdateCommand}"/>

var vm = new MyItem();this.BindingContext = vm;

this.UpdateCommand = new Command(() => { });

Xamarin.Forms.Command で Icommand を実装できる

Page 15: Xamarin.formsでのmvvm利用のコツ

ICommand の関係(パラメータ付き)

XAML

ViewModel+ModelClass

Codebehind

*.cs

<ContentPage> <Button Command="{Binding UpdateCommand}“ CommandParameter="..."/>

var vm = new MyItem();this.BindingContext = vm;

this.UpdateCommand = new Command<string>((param) => { });

Page 16: Xamarin.formsでのmvvm利用のコツ

イベントの場合

XAML

ViewModel+ModelClass

Codebehind

*.cs

<ContentPage> <Button Click="OnButtonClicked"/>

void OnButtonClicked(object sender, EventArgs e) { vm.UpdateCommand(); }Orbtn.Click += (s,e) => { vm.UpdteCommand(); }

ルールを決めればどちらでも良い

Page 17: Xamarin.formsでのmvvm利用のコツ

シーケンス図

XAML ViewModelCodebehin

d*.cs

Binding

Execute

Event

Create

Action

Page 18: Xamarin.formsでのmvvm利用のコツ

MVVM の得意なところ汎用ではない道具は何に特化しているのか?

Page 19: Xamarin.formsでのmvvm利用のコツ

View をプラットフォーム依存にする

View ViewModel Model

XAML による実装WPF

Windows StoreWindows PhoneXamarin.Forms

プラットフォーム非依存のライブラリにできる

ライブラリPCL

Shared Project

※ ただし、活用範囲が狭ければ、 ライブラリにする必要はない

Page 20: Xamarin.formsでのmvvm利用のコツ

ViewModel を TDD 可能にする

View ViewModel Model

プラットフォーム非依存にすることにより、

TDD で自動テストが可能になる

Page 21: Xamarin.formsでのmvvm利用のコツ

View

View の切り替えが可能

View ViewModel Model

View

動的に View を切り替えることが可能

※ ただし、現状の XAML(MS/Xamarin.Forms ) では、動的切り替えはあまり考えられてない。

Page 22: Xamarin.formsでのmvvm利用のコツ

別の MVVM フレームワークの利用

View ViewModel Model

インターフェースSystem.ComponentModel.INotifyPropertyChanged

System.Windows.Input.Icommand

が同じなので、他の MVVM フレームワークと互換性がある

WPF の MVVM, MvvmCross, Prism, Xamarin.Forms など

Page 23: Xamarin.formsでのmvvm利用のコツ

ViewModel のコツ

プラットフォーム非依存にするView を呼ばないプラットフォーム固有の機能を使わない

同時にデメリットでもある

Page 24: Xamarin.formsでのmvvm利用のコツ

Xamarin.Forms 特有の MVVMてこの原理を使って効果を最大化する

Page 25: Xamarin.formsでのmvvm利用のコツ

Xamarin.Forms の MVVM

WPF/Windows Store App の XAML と同じように作れるINotifyPropertyChanged 、 IComman

d のインターフェースがあるデザインビューがないので直打ち

Try&Error がやり辛い

Page 26: Xamarin.formsでのmvvm利用のコツ

単体のバインド

<StackLayout> <Label Text=" 設置場所情報 " /> <Label Text=" 施設名 " Font="Small" /> <Label Text="{Binding Item.LocationName}" /> <Label Text=" 住所 " Font="Small"/> <Label Text="{Binding Item.FullAddress}" />

this.SetBinding(Label.TextProperty, Item.Name)

ModelView のクラス構造を入れ子にできる

Page 27: Xamarin.formsでのmvvm利用のコツ

コレクションのバインド

<ListView ItemsSource="{Binding Items}"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout> <Label Text="{Binding LocationName}" />

listView.ItemsSource = Items

セル指定

セル内のレイアウトを作成

セルにバインド

Page 28: Xamarin.formsでのmvvm利用のコツ

数値フォーマットの表示

< Label Text="{Binding Count,StringFormat='{0}'}"/>

int 型

String.Format に変換適宜フォーマットするコンバータ利用

Xamarin.Forms.IValueConverter

Page 29: Xamarin.formsでのmvvm利用のコツ

その他の Xamarin.Forms のバインド機能

Part 4. Data Binding Basicshttp://developer.xamarin.com/guides/cross-

platform/xamarin-forms/xaml-for-xamarin-forms/data_binding_basics/

Part 5. From Data Bindings to MVVMhttp://developer.xamarin.com/guides/cross-

platform/xamarin-forms/xaml-for-xamarin-forms/data_bindings_to_mvvm/

Page 30: Xamarin.formsでのmvvm利用のコツ

AEDSearch によるデモ

Page 31: Xamarin.formsでのmvvm利用のコツ

TMPuzzleXForms によるデモ

Page 32: Xamarin.formsでのmvvm利用のコツ

MVVM の限界限界があるからこそ、最大限の利用が可能。それ以後は場を変える。

Page 33: Xamarin.formsでのmvvm利用のコツ

画面遷移の不都合

ViewModel がプラットフォーム非依存のため、 View (プラットフォーム依存)ができない / やりにくい。this.Navigation.PushAsync素直に View のイベントを使う

Page 34: Xamarin.formsでのmvvm利用のコツ

複雑なイベント処理が ICommand ではやりづらい

ICommand では静的なパラメータのみ利用可能<Button Command=“…”

CommandParameter=“…” />素直にイベントを利用コードビハイドから ViewModel へ渡す

Page 35: Xamarin.formsでのmvvm利用のコツ

GoF Command パターン

大量の命令 ( コマンド ) を一括で扱うSystem.Windows.Input.ICommandSendMessageEevntHandler

パラメタの型が失われる欠点

Page 36: Xamarin.formsでのmvvm利用のコツ

その他の欠点

プロパティ伝播が過敏非同期 (async/await) が使えないView での不意な重たい処理に弱い

コレクションの変更に過敏プラットフォーム依存データが扱いにくい

Page 37: Xamarin.formsでのmvvm利用のコツ

と云う限界を知って MVVM を使う

XAML+ イベントの使い分けRx の利用C++, F# でパイプの利用動的 XAML ロード

Page 38: Xamarin.formsでのmvvm利用のコツ

参考文献

Cross-Platform User Interfaces with Xamarin.Formshttp://developer.xamarin.com/guides/cross-platform/xamarin-forms/

MvvmCrosshttps://github.com/MvvmCross

Prism 5.0 for .NET 4.5http://compositewpf.codeplex.com/releases/view/117297

Reactive Alliancehttp://www.reactivealliance.com/

AED Opendata Search Samplehttp://code.msdn.microsoft.com/AED-Opendata-Search-Sample-117dfafc

moonmile/TMPuzzleXFormshttps://github.com/moonmile/TMPuzzleXForms

moonmile/XFormsPreviewerhttps://github.com/moonmile/XFormsPreviewer