46
1 Model-View-ViewModel and friends… Jonas Follesø Senior Consultant Capgemini

MVVM Design Pattern NDC2009

Embed Size (px)

DESCRIPTION

Presentation on the Model-View-ViewModel Design Pattern for Silverlight application. Presented by Jonas Follesø at the Norwegian Developer Conference 2009.

Citation preview

Page 1: MVVM Design Pattern NDC2009

1

Model-View-ViewModel and friends…

Jonas FollesøSenior ConsultantCapgemini

Page 2: MVVM Design Pattern NDC2009

2

Page 3: MVVM Design Pattern NDC2009

3

Agenda

MVVM IntoMVVM and DISupporting Patterns

CommandEvent AggregatorService Locator

Q&A

Page 4: MVVM Design Pattern NDC2009

4

Dive Log App

Page 5: MVVM Design Pattern NDC2009

5

Dive Log Application

demo

Page 6: MVVM Design Pattern NDC2009

6

Everything in code behind…is probably not a good idea

Page 7: MVVM Design Pattern NDC2009

7

A team of sad coders and designers

FAIL!

Page 8: MVVM Design Pattern NDC2009

8

Lasagna

FTW!

Page 9: MVVM Design Pattern NDC2009
Page 10: MVVM Design Pattern NDC2009

10

Different people reading about MVC in different places take different ideas from it and describe these as “MVC”.

Martin Fowler, GUI Architectures Essay (July 2006)

Page 11: MVVM Design Pattern NDC2009

11Separated Presentation Patterns

Page 12: MVVM Design Pattern NDC2009

12

Data & Domain Logic(Model)

UI(View)

Interaction (Controller/Presenter)

Page 13: MVVM Design Pattern NDC2009

13

Presentation Model is of a fully self-contained class that represents all the data and behavior of the UI, but without any of the controls used to render that UI on the screen. A view then simply projects the state of the presentation model onto the glass.

Martin Fowler, Presentation Model Essay, July 2004

Page 14: MVVM Design Pattern NDC2009

14

The most annoying part of Presentation Model is the synchronization between Presentation Model and view…

Martin Fowler, GUI Architectures Essay, July 2004

Page 15: MVVM Design Pattern NDC2009

15

Ideally some kind of framework could handle this, which I'm hoping will happen some day with technologies like .NET's data binding.

Martin Fowler, Presentation Model Essay, July 2004

Page 16: MVVM Design Pattern NDC2009

16

Everything in code-behind

Data Model

View

XAML

Code-BehindEvent Handlers

Page 17: MVVM Design Pattern NDC2009

17

Model – View – ViewModel

Data Model

View

XAML

Code-Behind

View Model

State + Operations

Change notification

Data-binding and commands

Page 18: MVVM Design Pattern NDC2009

18

Data BindingImplement INotifyPropertyChanged and use ObservableCollection<T> for collections

View <ListBox ItemsSource="{Binding Path=Dives}" SelectedItem="{Binding Path=SelectedDive, Mode=TwoWay}" />

View Model

State + Operations

Page 19: MVVM Design Pattern NDC2009

19

Data BindingImplement INotifyPropertyChanged and use ObservableCollection<T> for collections

View

XAML

Code-Behind

View Modelpublic class DiveViewModel : INotifyPropertyChanged{ public event PropertyChangedEventHandler PropertyChanged; public ObservableCollection<Dive> Dives { ... } public Dive SelectedDive { ... }}

Page 20: MVVM Design Pattern NDC2009

21

A simple View Model

demo

Page 21: MVVM Design Pattern NDC2009

22

“Once a developer becomes comfortable with WPF and MVVM, it can be difficult to differentiate the two.”

Josh Smith, WPF Apps With The Model-View-ViewModel Design Pattern

Page 22: MVVM Design Pattern NDC2009

23

“MVVM is the lingua franca of WPF developers because it is well suited to the WPF platform, and WPF was designed to make it easy to build applications using the MVVM pattern”

Josh Smith, WPF Apps With The Model-View-ViewModel Design Pattern

Page 23: MVVM Design Pattern NDC2009

24

User Interaction

But what about Word?

Viewprivate void btnSave_Clicked(object sender, ExecutedEventArgs e){ ((PageViewModel)DataContext).Save();}

Page 24: MVVM Design Pattern NDC2009

25

Objects are used to represent actions. A command object encapsulates an action and its parameters.

This allows a decoupling of the invoker of the command and the handlers of the command.

Page 25: MVVM Design Pattern NDC2009

26

Command Pattern

public interface ICommand{

event EventHandler CanExecuteChanged;

bool CanExecute(object parameter);void Execute(object parameter);

}

Page 26: MVVM Design Pattern NDC2009

27

Commands in SilverlightView

<Button Content=“Delete Dive” commands:Click.CommandParameter=“{Binding}” commands:Click.Command=“DeleteCommand” />

View Modelprivate ICommand DeleteCommand { get; private set; }

public PageViewModel(){ DeleteCommand = new DelegateCommand<Dive>(DeleteDive);}

private void DeleteDive(Dive dive){ // code to save dives..}

Page 27: MVVM Design Pattern NDC2009

28

Commands

demo

Page 28: MVVM Design Pattern NDC2009

30

Dealing with dependencies

The View Model is coupled with the web service.

Makes code less flexible for changeMakes code harder to test

Object should not be responsible for creating their own dependencies – Inversion of Control

Page 29: MVVM Design Pattern NDC2009

31

Dependency Injection (DI)

One form of Inversion of Control (IoC) Create dependencies outside the object and, inject them into it

But who creates the dependency?

Presentation Modelpublic PageViewModel(IDiveLogServiceClient proxy){ this.proxy = proxy}

Page 30: MVVM Design Pattern NDC2009

32

Dependency Injection by hand

Should the page be responsible for creating dependencies?

Viewpublic Page(){ InitializeComponent(); if (HtmlPage.IsEnabled) this.DataContext = new PageViewModel(new DiveLogServiceClient()); else this.DataContext = new PageViewModel(new ServiceStub());}

Page 31: MVVM Design Pattern NDC2009

33

IoC Containers

View Model

public PageViewModel(IDiveLogServiceClient proxy){ this.proxy = proxy}

Viewpublic Page(){ InitializeComponent(); IKernel iocContainer = new StandardKernel(); this.DataContext = iocContainer.Get<PageViewModel>();}

Page 32: MVVM Design Pattern NDC2009

34

Who came first?

Page 33: MVVM Design Pattern NDC2009

35

View Model First

The ViewModel creates the view (usually through an IoC container).

View Model

public MyViewModel(IMyView myView){

myView.Model = this;}

Page 34: MVVM Design Pattern NDC2009

36

View First

The View has a relationship to its ViewModel (usually through data binding).

View<UserControl.DataContext> <dive:PageViewModel /></UserControl.DataContext>

Available at design time (Blend support)Need to find a way to use IoC and set DataContext declaratively…

Page 35: MVVM Design Pattern NDC2009

37

Using DI on the ViewModel

demo

Page 36: MVVM Design Pattern NDC2009

38

View Model Communication?

View Model

View Model

View Model View Model

View Model

View Model

View Model View Model

FAIL!

Page 37: MVVM Design Pattern NDC2009

39

It’s all about coupling…

Page 38: MVVM Design Pattern NDC2009

40

... or how to decouple…

Page 39: MVVM Design Pattern NDC2009

41

Event Aggregator

View Model

View Model

View Model View Model

View Model

View Model

View Model View Model

Page 40: MVVM Design Pattern NDC2009

42

Event Aggregator

View Model

View Model

View Model View Model

View Model

View Model

View Model View Model

Event Aggregator

Page 41: MVVM Design Pattern NDC2009

43

View Model Communication

Data Model

View

XAML

Code-Behind

Data Model

View

XAML

Code-Behind

Message

View Model

State + OperationsView Model

State + Operations

View

XAML

Code-Behind

MessageEvent AggregatorView Model

State + Operations

Publish messages

Subscribe to messages

Page 42: MVVM Design Pattern NDC2009

44

ViewModel communication using Event Aggregator

demo

Page 43: MVVM Design Pattern NDC2009

45

MVVM Cheat Sheet

Put State and Behaviour in View Model

Invoke Operations using Commands

Cross View Model communication through Mediator/Event Aggregator

Service Locator to bind View to View Model (View first)

Page 44: MVVM Design Pattern NDC2009

46

SummarySeperated Presentation Decoupling

Page 45: MVVM Design Pattern NDC2009

47

Q & A

Page 46: MVVM Design Pattern NDC2009

48

Photo Copyright Notices

All diving photos taken by Hege Røkenes and licensed under the creative commons license. http://flickr.com/photos/hegerokenes/

Photos of Martin Fowler taken by Dave Thomas and licensed under the creative commons license.http://flickr.com/photos/pragdave/