MVVM Design Pattern NDC2009
-
Upload
jonas-folleso -
Category
Technology
-
view
8.076 -
download
2
description
Transcript of MVVM Design Pattern NDC2009
1
Model-View-ViewModel and friends…
Jonas FollesøSenior ConsultantCapgemini
2
3
Agenda
MVVM IntoMVVM and DISupporting Patterns
CommandEvent AggregatorService Locator
Q&A
4
Dive Log App
5
Dive Log Application
demo
6
Everything in code behind…is probably not a good idea
7
A team of sad coders and designers
FAIL!
8
Lasagna
FTW!
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)
11Separated Presentation Patterns
12
Data & Domain Logic(Model)
UI(View)
Interaction (Controller/Presenter)
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
14
The most annoying part of Presentation Model is the synchronization between Presentation Model and view…
Martin Fowler, GUI Architectures Essay, July 2004
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
16
Everything in code-behind
Data Model
View
XAML
Code-BehindEvent Handlers
17
Model – View – ViewModel
Data Model
View
XAML
Code-Behind
View Model
State + Operations
Change notification
Data-binding and commands
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
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 { ... }}
21
A simple View Model
demo
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
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
24
User Interaction
But what about Word?
Viewprivate void btnSave_Clicked(object sender, ExecutedEventArgs e){ ((PageViewModel)DataContext).Save();}
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.
26
Command Pattern
public interface ICommand{
event EventHandler CanExecuteChanged;
bool CanExecute(object parameter);void Execute(object parameter);
}
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..}
28
Commands
demo
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
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}
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());}
33
IoC Containers
View Model
public PageViewModel(IDiveLogServiceClient proxy){ this.proxy = proxy}
Viewpublic Page(){ InitializeComponent(); IKernel iocContainer = new StandardKernel(); this.DataContext = iocContainer.Get<PageViewModel>();}
34
Who came first?
35
View Model First
The ViewModel creates the view (usually through an IoC container).
View Model
public MyViewModel(IMyView myView){
myView.Model = this;}
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…
37
Using DI on the ViewModel
demo
38
View Model Communication?
View Model
View Model
View Model View Model
View Model
View Model
View Model View Model
FAIL!
39
It’s all about coupling…
40
... or how to decouple…
41
Event Aggregator
View Model
View Model
View Model View Model
View Model
View Model
View Model View Model
42
Event Aggregator
View Model
View Model
View Model View Model
View Model
View Model
View Model View Model
Event Aggregator
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
44
ViewModel communication using Event Aggregator
demo
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)
46
SummarySeperated Presentation Decoupling
47
Q & A
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/