SlideShare a Scribd company logo
MVVM Light v5
v1.0
Ir Denis VOITURON
http://www.dvoituron.be
Pattern
MVVM Light - v1.0 2
Model
Business Logic
View
Presentation UI
ViewModel
Presentation Logic
Command
Binding
Method call
Event
MVVMMODEL VIEW VIEWMODEL
Pattern
MVVM Light - v1.0 3
Model
Business Logic
View
Presentation UI
ViewModel
Presentation Logic
Command
Binding
Method call
Event
Friend
LastName
FirstName
DateOfBirth
ImageUrl
ObservableObject
FriendPage
<Page DataContext="{Binding Friend}">
<TextBlock Text="{Binding FullName}" />
<TextBlock Text="{Binding Age}" />
<Image Source="{Binding ImageSource}" />
</Page>
FriendViewModel
FullName
Age
ImageSource
ViewModelBase
NuGet : MVVM Light Libraries Only (PCL)
MVVM Light v5
 Toolkit to help MVVM developments
◦ Windows Presentation Foundation (3.5, 4, 4.5, 4.5.1)
◦ Silverlight (4 and 5)
◦ Windows Phone (7.1, 8, 8.1 Silverlight, 8.1 RT)
◦ Windows Store (8, 8.1)
◦ Xamarin Android
◦ Xamarin iOS
◦ Xamarin Forms
 Open Source project
 Supported by Microsoft
MVVM Light - v1.0 4
MVVM Light
Fundamentals
Model - DataService
MVVM Light - v1.0 6
public interface IDataService
{
Task<Friend[]> GetFriendsAsync();
}
public class DataService : IDataService
{
public async Task<Friend[]> GetFriendsAsync()
{
...
}
}
public class DesignDataService : IDataService
{
public async Task<Friend[]> GetFriendsAsync()
{
...
}
}
Model
Model – Data Classes
MVVM Light - v1.0 7
public class Friend
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public string ImageUrl { get; set; }
}
public class Friend : ObservableObject
{
private string _firstName = String.Empty;
public string FirstName
{
get { return _firstName; }
set
{
Set(() => this.FirstName, ref _firstName, value);
}
}
Model
IoC – Inversion of Control
MVVM Light - v1.0 8
public class MainViewModel
{
public MainViewModel()
{
_dataService = new DataService();
}
}
public class MainViewModel
{
public MainViewModel(IDataService dataservice)
{
_dataService = dataservice;
}
}
DataService for Test, for Production, for Design, …
 An IoC container is
◦ Responsible to create services when needed.
◦ Responsible for injecting them.
◦ Responsible for caching the objects.
◦ And providing access to them.
View
Model
ViewModelLocator
MVVM Light - v1.0 9
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<IDataService, DataService>();
SimpleIoc.Default.Register<MainViewModel>();
}
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
}
View
Model
ViewModelLocator
MVVM Light - v1.0 10
View
Model
public class MainViewModel : ViewModelBase
{
public MainViewModel(Model.IDataService dataService)
{
}
}
<Application
x:Class="MyApplication.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewmodel="using:MyApplication.ViewModel"
xmlns:local="using:MyApplication">
<Application.Resources>
<viewmodel:ViewModelLocator x:Key="Locator" />
</Application.Resources>
</Application>
<Page x:Class="MyApplication.View.MainPage"
...
DataContext="{Binding Source={StaticResource Locator}, Path=Main}">
NotifyPropertyChanged
MVVM Light - v1.0 11
View
Model
public class Friend : ViewModelBase
{
private string _firstName = String.Empty;
public string FirstName
{
get { return _firstName; }
set
{
Set(() => this.FirstName, ref _firstName, value);
}
}
private bool _isWorking = false;
public bool IsWorking
{
get { return _isWorking; }
set
{
Set(ref _isWorking, value);
}
}
RelayCommand
MVVM Light - v1.0 12
private RelayCommand<FriendItem> _displayDetailCommand;
private void ExecuteDisplayDetailCommand(FriendItem item)
{
Messenger.Default.Send<FriendItem>(item);
_navigationService.NavigateTo(ViewModel.ViewModelLocator.FRIENDDETAIL_PAGEKEY, item.ID);
}
private void ExecuteDisplayDetailCommand(FriendItem item)
{
Messenger.Default.Send<FriendItem>(item);
_navigationService.NavigateTo(ViewModel.ViewModelLocator.FRIENDDETAIL_PAGEKEY,
item.ID);
}
private bool CanExecuteDisplayDetailCommand(FriendItem item)
{
return true;
}
Navigation & Dialog
MVVM Light - v1.0 13
View
Model
public class ViewModelLocator
{
public const string DAYDETAIL_PAGEKEY = "DayDetailPage";
static ViewModelLocator()
{
...
// NavigationService
SimpleIoc.Default.Register<INavigationService>(() =>
{
var navigationService = new Model.NavigationService();
navigationService.Configure(DAYDETAIL_PAGEKEY, typeof(View.DayDetailPage));
navigationService.Configure(SEARCH_PAGEKEY, typeof(View.SearchPage));
navigationService.Configure(TIMEDETAIL_PAGEKEY, typeof(View.TimeDetailView));
return navigationService;
});
// DialogService
SimpleIoc.Default.Register<IDialogService>(() =>
{
return new DialogService();
});
...
}
}
navigation.NavigateTo(ViewModelLocator.DAYDETAIL_PAGEKEY, e.Date);
View
Model
Navigation between ViewModels
 In Source ViewModel
◦ Call NavigateTo method
 In Target ViewModel
◦ Implement INavigableViewModel
◦ Override Page.OnNavigateTo
MVVM Light - v1.0 14
public interface INavigableViewModel
{
void Activate(object parameter);
void Deactivate(object parameter);
}
navigation.NavigateTo(ViewModelLocator.DAYDETAIL_PAGEKEY, e.Date);
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var navigableViewModel = this.DataContext as Model.INavigableViewModel;
if (navigableViewModel != null)
navigableViewModel.Activate(e.Parameter);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
var navigableViewModel = this.DataContext as Model.INavigableViewModel;
if (navigableViewModel != null)
navigableViewModel.Deactivate(e.Parameter);
}
Dialog from ViewModel
 To display a dialog message, use
DialogService registered in
ViewModelLocator
MVVM Light - v1.0 15
View
Model
await _dialogService.ShowMessage("Let's go to the friend detail.", "Title", "OK", () =>
{
// This code will be executed after OK click.
});
await _dialogService.ShowMessage("Continue?", "Title", "OK", "Cancel", (ok) =>
{
if (ok)
{
_navigationService.NavigateTo(ViewModel.ViewModelLocator.FRIENDDETAIL_PAGEKEY,
_selectedItem.ID);
}
});
Async
 CheckBeginInvokeOnUI
MVVM Light - v1.0 16
View
Model
public async Task LoadDataAsync()
{
await Task.Run(async () =>
{
var data = await _dataService.GetMyDataAsync();
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
this.Items.AddRange(data);
...
});
});
}
public sealed partial class App : Application
{
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
DispatcherHelper.Initialize();
...
InDesignMode, don’t user asynchronous tasks
DataContext
 From ViewModel Locator
◦ If constructor of ViewModel use only
IoC parameters.
MVVM Light - v1.0 17
View
<Page x:Class="MyApplication.View.MainPage"
...
DataContext="{Binding Path=Main, Source={StaticResource Locator}}">
public class MainViewModel : ViewModelBase
{
public MainViewModel(IDataService dataService, INavigationService navigationService)
{
...
}
}
DataContext
 From Designer Creator
◦ If IoC Locator can not find the correct constructor
MVVM Light - v1.0 18
View
#if DEBUG
/// <summary>
/// This constructor is used in the Windows Phone app at design time,
/// for the Blend visual designer.
/// </summary>
public DetailViewModel() : this(SimpleIoc.Default.GetInstance<Model.IDataService>(),
SimpleIoc.Default.GetInstance<INavigationService>(),
0)
{
...
}
#endif
<Page x:Class="MyApplication.View.DetailPage"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
...
xmlns:vm="using:MyApplication.ViewModel"
d:DataContext="{d:DesignInstance Type=vm:DetailViewModel,
IsDesignTimeCreatable=True}">
public DetailViewModel(IDataService dataService, INavigationService navigationService, int id)
{
...
MVVM Light
Design Mode
Design Mode
 Drawing UI with Visual Studio (Blend)
MVVM Light - v1.0 20
DataService
 DesignDataService
MVVM Light - v1.0 21
public class DesignDataService : IDataService
{
private List<Friend> _friends = new List<Friend>();
public DesignDataService()
{
_friends.Add(new Friend() { LastName = "Voituron", FirstName = "Denis", ... });
_friends.Add(new Friend() { LastName = "Dubois", FirstName = "Anne", ... });
...
}
}
Model
Navigation
 DesignNavigationService
MVVM Light - v1.0 22
public class DesignNavigationService : INavigationService
{
public string CurrentPageKey
{
get
{
Debug.WriteLine("DesignNavigationService.CurrentPageKey");
return String.Empty;
}
}
public void GoBack()
{
Debug.WriteLine("DesignNavigationService.GoBack()");
}
public void NavigateTo(string pageKey, object parameter)
{
Debug.WriteLine(String.Format("DesignNavigationService.NavigateTo("{0}", {1})", pageKey,
parameter.ToString()));
}
public void NavigateTo(string pageKey)
{
Debug.WriteLine(String.Format("DesignNavigationService.NavigateTo("{0}")", pageKey));
}
}
Model
Dialog
 DesignDialogService
MVVM Light - v1.0 23
public class DesignDialogService : IDialogService
{
public System.Threading.Tasks.Task ShowError(Exception error, string title,
string buttonText, Action afterHideCallback)
{
throw new NotImplementedException();
}
public System.Threading.Tasks.Task ShowError(string message, string title,
string buttonText, Action afterHideCallback)
{
throw new NotImplementedException();
}
...
}
Model
ViewModelLocator
MVVM Light - v1.0 24
public class ViewModelLocator
{
static ViewModelLocator()
{
if (ViewModelBase.IsInDesignModeStatic)
{
DispatcherHelper.Initialize();
// DataService, Navigation and Dialog
SimpleIoc.Default.Register<IDataService>(() => new DesignDataService());
SimpleIoc.Default.Register<INavigationService>(() => new DesignNavigationService());
SimpleIoc.Default.Register<IDialogService>(() => new DesignDialogService());
// ViewModels
SimpleIoc.Default.Register<FriendViewModel>();
}
else
{
}
}
}
View
Model
MVVM Light
Best Practices
Objectives
 Define a manageable structure
 Create Design data to draw UI easier
 Create a DataService class to centralize all
external requests
 Use always asynchronous operations
 Display a working progress bar
MVVM Light - v1.0 26
Universal project
 Create Blank App (Universal App)
 Add NuGet Packages for Solution
 Select MVVM Light Libraries Only (PCL)
◦ WPF4.5 (and 4.5.1)
◦ Windows Phone (Silverlight) 8
◦ Windows Phone (Silverlight) 8.1
◦ Windows Phone (RT) 8.1
◦ Windows Store (RT) 8 and 8.1
◦ Xamarin Android
◦ Xamarin iOS
◦ PCL (for class libraries)
MVVM Light - v1.0 27
 Universal Project
Shared
Design
DesignDataService
DesignDialogService
DesignNavigationService
Helpers
Extensions
VisualTreeHelper
Model
DataService
IDataService
INavigableViewModel
NavigationService
Friend
ViewModel
Friend
FriendViewModel
ViewModelLocator
Project Structure
MVVM Light - v1.0 28
WindowsPhone
Assets
Logo.png
Controls
SampleControl
View
FriendPage
Windows
Assets
Logo.png
Controls
SampleControl
View
FriendPage
Asynchronous
 IDataServices
 DesignDataService
MVVM Light - v1.0 29
public interface IDataService
{
Task<Friend[]> GetFriendsAsync();
}
public class DesignDataService : Model.IDataService
{
List<Model.Friend> _friends = new List<Model.Friend>();
public DesignDataService()
{
_friends.Add(new Model.Friend() { FriendID = 1, LastName = "Voituron", ...
_friends.Add(new Model.Friend() { FriendID = 2, LastName = "Dubois", ...
}
#pragma warning disable 1998 // Supress warning "This async method lacks 'await' op."
public async Task<Model.Friend[]> GetFriendsAsync()
{
return _friends.ToArray();
}
#pragma warning restore 1998
}
Asynchronous
 ViewModel
MVVM Light - v1.0 30
public async void LoadDataAsync()
{
this.IsWorking = true;
if (this.IsInDesignMode)
{
var data = await _dataService.GetFriendsAsync();
this.Friends.AddRange(data);
return;
}
else
{
await Task.Run(async () =>
{
var data = await _dataService.GetFriendsAsync();
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
this.Friends.AddRange(data);
});
});
}
this.IsWorking = false;
}
MVVM Light
References
References
 http://www.mvvmlight.net/doc
 http://www.spikie.be/blog/post/2013/04/12/10-
things-you-might-have-missed-about-MVVM-
Light.aspx
 http://developer.nokia.com/community/wiki/How_to
_use_MVVM_Light_Toolkit_for_Windows_Phone
 https://marcominerva.wordpress.com
 https://github.com/dvoituron/SampleMvvmLight
MVVM Light - v1.0 32

More Related Content

PDF
MVVM Light Toolkit Works Great, Less Complicated
PPTX
MVVM - Model View ViewModel
PPTX
MVVM Design Pattern NDC2009
PPTX
Training: MVVM Pattern
PPTX
Software architectural design patterns(MVC, MVP, MVVM, VIPER) for iOS
PDF
當ZK遇見Front-End
ODP
Design Patterns in ZK: Java MVVM as Model-View-Binder
PPTX
Knockout js
MVVM Light Toolkit Works Great, Less Complicated
MVVM - Model View ViewModel
MVVM Design Pattern NDC2009
Training: MVVM Pattern
Software architectural design patterns(MVC, MVP, MVVM, VIPER) for iOS
當ZK遇見Front-End
Design Patterns in ZK: Java MVVM as Model-View-Binder
Knockout js

What's hot (20)

PPTX
Knockout implementing mvvm in java script with knockout
PPTX
PPTX
Fundaments of Knockout js
PDF
ASP.NET MVC 3
PPTX
ASP.NET MVC for Begineers
PDF
Knockout js session
PDF
From mvc to viper
PPT
MSDN - ASP.NET MVC
PPTX
Asp.net MVC training session
PPT
Mvc architecture
PDF
Why Vue.js?
PDF
An introduction to knockout.js
KEY
Knockout.js presentation
PPT
CTTDNUG ASP.NET MVC
PPTX
ASP.NET MVC Presentation
PPTX
KnockOutjs from Scratch
PPT
ASP .net MVC
PDF
WJAX 2012 - Web Apps With AngularJS
PDF
Vue, vue router, vuex
PPTX
Mvvm knockout vs angular
Knockout implementing mvvm in java script with knockout
Fundaments of Knockout js
ASP.NET MVC 3
ASP.NET MVC for Begineers
Knockout js session
From mvc to viper
MSDN - ASP.NET MVC
Asp.net MVC training session
Mvc architecture
Why Vue.js?
An introduction to knockout.js
Knockout.js presentation
CTTDNUG ASP.NET MVC
ASP.NET MVC Presentation
KnockOutjs from Scratch
ASP .net MVC
WJAX 2012 - Web Apps With AngularJS
Vue, vue router, vuex
Mvvm knockout vs angular
Ad

Viewers also liked (7)

PPTX
Pattern MVVM avec MVVM Light Toolkit
PDF
BK2011 Trafikanten - Et webprosjekt med full oppgradering av karttjenester
PPT
Caliburn.micro jump start composite applications for WPF, Silverlight and WP7
PPTX
Understanding The MVVM Pattern (TechDays Belgium)
PPTX
A Day In The Life Of A WPF/SL Integrator
PPTX
Cross platform mobile apps using .NET
PPTX
MVVM ( Model View ViewModel )
Pattern MVVM avec MVVM Light Toolkit
BK2011 Trafikanten - Et webprosjekt med full oppgradering av karttjenester
Caliburn.micro jump start composite applications for WPF, Silverlight and WP7
Understanding The MVVM Pattern (TechDays Belgium)
A Day In The Life Of A WPF/SL Integrator
Cross platform mobile apps using .NET
MVVM ( Model View ViewModel )
Ad

Similar to MVVM Lights (20)

PPTX
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
PDF
Portable Class Libraries and MVVM
PPTX
WPF For Beginners - Learn in 3 days
PPTX
Presentation Model
PPTX
Adopting MVVM
PPTX
MVVM with WPF
 
PPTX
Introduction to MVVM Framework
PPTX
Applied MVVM in Windows 8 apps: not your typical MVVM session!
PPTX
Advanced MVVM in Windows 8
PPTX
Prism library and MVVM
PPTX
Mvvm in the real world tccc10
PPT
Model View ViewModel
PPTX
MvvmQuickCross for Windows Phone
PDF
How I Accidentally Discovered MVVM
PPTX
WPF with MVVM: From the Trenches
KEY
What's new in Silverlight 5
PPSX
Android architecture components
PPTX
Windows Phone App with MVVM design patten
PPTX
Real-world Model-View-ViewModel for WPF
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
Portable Class Libraries and MVVM
WPF For Beginners - Learn in 3 days
Presentation Model
Adopting MVVM
MVVM with WPF
 
Introduction to MVVM Framework
Applied MVVM in Windows 8 apps: not your typical MVVM session!
Advanced MVVM in Windows 8
Prism library and MVVM
Mvvm in the real world tccc10
Model View ViewModel
MvvmQuickCross for Windows Phone
How I Accidentally Discovered MVVM
WPF with MVVM: From the Trenches
What's new in Silverlight 5
Android architecture components
Windows Phone App with MVVM design patten
Real-world Model-View-ViewModel for WPF

More from Denis Voituron (20)

PDF
Go lean, Go green
PDF
DevDay 2021 - Codez comme un ninja
PDF
Azure DevOps Tests Plan
PDF
.Net passé, présent et futur
PPTX
MIC QRS "JWT, la superstar pour sécuriser vos WebAPI"
PDF
Azure Pipelines - Et si on arrêtait de mettre en production avec des Disquettes
PDF
GitHub et Microsoft Azure DevOps - Le mariage parfait
PPTX
Azure for Dev
PPTX
DevDay 2018 - Blazor
PPTX
Les méthodes agiles dans TFS
PPTX
Awareness Oniryx - Mai 2018
PDF
A la découverte de TypeScript
PDF
Le futur de .NET
PPTX
Procédures CLR pour SQL Server : avantages et inconvénients
PPTX
Microsoft Experieces 2016 - Retour d’expériences sur TFS Online
PPTX
Développer avec un Simple Object Mapping Toolkit pour SQL Server
PPTX
Les cinq bonnes pratiques des Tests Unitaires dans un projet Agile
PPTX
DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit
PPTX
Presentation MIC SummerCamp 2015 WaterStock
PPTX
Scrum Guide
Go lean, Go green
DevDay 2021 - Codez comme un ninja
Azure DevOps Tests Plan
.Net passé, présent et futur
MIC QRS "JWT, la superstar pour sécuriser vos WebAPI"
Azure Pipelines - Et si on arrêtait de mettre en production avec des Disquettes
GitHub et Microsoft Azure DevOps - Le mariage parfait
Azure for Dev
DevDay 2018 - Blazor
Les méthodes agiles dans TFS
Awareness Oniryx - Mai 2018
A la découverte de TypeScript
Le futur de .NET
Procédures CLR pour SQL Server : avantages et inconvénients
Microsoft Experieces 2016 - Retour d’expériences sur TFS Online
Développer avec un Simple Object Mapping Toolkit pour SQL Server
Les cinq bonnes pratiques des Tests Unitaires dans un projet Agile
DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit
Presentation MIC SummerCamp 2015 WaterStock
Scrum Guide

Recently uploaded (20)

PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
iTop VPN Crack Latest Version Full Key 2025
PPTX
Monitoring Stack: Grafana, Loki & Promtail
PDF
Website Design Services for Small Businesses.pdf
PDF
Digital Systems & Binary Numbers (comprehensive )
PPTX
WiFi Honeypot Detecscfddssdffsedfseztor.pptx
PDF
17 Powerful Integrations Your Next-Gen MLM Software Needs
PDF
Download FL Studio Crack Latest version 2025 ?
PDF
Tally Prime Crack Download New Version 5.1 [2025] (License Key Free
PDF
Nekopoi APK 2025 free lastest update
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Salesforce Agentforce AI Implementation.pdf
PDF
How to Make Money in the Metaverse_ Top Strategies for Beginners.pdf
PPTX
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
PPTX
Patient Appointment Booking in Odoo with online payment
PDF
Complete Guide to Website Development in Malaysia for SMEs
PPTX
Weekly report ppt - harsh dattuprasad patel.pptx
PDF
How AI/LLM recommend to you ? GDG meetup 16 Aug by Fariman Guliev
DOCX
Greta — No-Code AI for Building Full-Stack Web & Mobile Apps
PDF
Design an Analysis of Algorithms I-SECS-1021-03
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
iTop VPN Crack Latest Version Full Key 2025
Monitoring Stack: Grafana, Loki & Promtail
Website Design Services for Small Businesses.pdf
Digital Systems & Binary Numbers (comprehensive )
WiFi Honeypot Detecscfddssdffsedfseztor.pptx
17 Powerful Integrations Your Next-Gen MLM Software Needs
Download FL Studio Crack Latest version 2025 ?
Tally Prime Crack Download New Version 5.1 [2025] (License Key Free
Nekopoi APK 2025 free lastest update
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Salesforce Agentforce AI Implementation.pdf
How to Make Money in the Metaverse_ Top Strategies for Beginners.pdf
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
Patient Appointment Booking in Odoo with online payment
Complete Guide to Website Development in Malaysia for SMEs
Weekly report ppt - harsh dattuprasad patel.pptx
How AI/LLM recommend to you ? GDG meetup 16 Aug by Fariman Guliev
Greta — No-Code AI for Building Full-Stack Web & Mobile Apps
Design an Analysis of Algorithms I-SECS-1021-03

MVVM Lights

  • 1. MVVM Light v5 v1.0 Ir Denis VOITURON http://www.dvoituron.be
  • 2. Pattern MVVM Light - v1.0 2 Model Business Logic View Presentation UI ViewModel Presentation Logic Command Binding Method call Event MVVMMODEL VIEW VIEWMODEL
  • 3. Pattern MVVM Light - v1.0 3 Model Business Logic View Presentation UI ViewModel Presentation Logic Command Binding Method call Event Friend LastName FirstName DateOfBirth ImageUrl ObservableObject FriendPage <Page DataContext="{Binding Friend}"> <TextBlock Text="{Binding FullName}" /> <TextBlock Text="{Binding Age}" /> <Image Source="{Binding ImageSource}" /> </Page> FriendViewModel FullName Age ImageSource ViewModelBase NuGet : MVVM Light Libraries Only (PCL)
  • 4. MVVM Light v5  Toolkit to help MVVM developments ◦ Windows Presentation Foundation (3.5, 4, 4.5, 4.5.1) ◦ Silverlight (4 and 5) ◦ Windows Phone (7.1, 8, 8.1 Silverlight, 8.1 RT) ◦ Windows Store (8, 8.1) ◦ Xamarin Android ◦ Xamarin iOS ◦ Xamarin Forms  Open Source project  Supported by Microsoft MVVM Light - v1.0 4
  • 6. Model - DataService MVVM Light - v1.0 6 public interface IDataService { Task<Friend[]> GetFriendsAsync(); } public class DataService : IDataService { public async Task<Friend[]> GetFriendsAsync() { ... } } public class DesignDataService : IDataService { public async Task<Friend[]> GetFriendsAsync() { ... } } Model
  • 7. Model – Data Classes MVVM Light - v1.0 7 public class Friend { public string FirstName { get; set; } public string LastName { get; set; } public DateTime DateOfBirth { get; set; } public string ImageUrl { get; set; } } public class Friend : ObservableObject { private string _firstName = String.Empty; public string FirstName { get { return _firstName; } set { Set(() => this.FirstName, ref _firstName, value); } } Model
  • 8. IoC – Inversion of Control MVVM Light - v1.0 8 public class MainViewModel { public MainViewModel() { _dataService = new DataService(); } } public class MainViewModel { public MainViewModel(IDataService dataservice) { _dataService = dataservice; } } DataService for Test, for Production, for Design, …  An IoC container is ◦ Responsible to create services when needed. ◦ Responsible for injecting them. ◦ Responsible for caching the objects. ◦ And providing access to them. View Model
  • 9. ViewModelLocator MVVM Light - v1.0 9 public class ViewModelLocator { static ViewModelLocator() { ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); SimpleIoc.Default.Register<IDataService, DataService>(); SimpleIoc.Default.Register<MainViewModel>(); } public MainViewModel Main { get { return ServiceLocator.Current.GetInstance<MainViewModel>(); } } } View Model
  • 10. ViewModelLocator MVVM Light - v1.0 10 View Model public class MainViewModel : ViewModelBase { public MainViewModel(Model.IDataService dataService) { } } <Application x:Class="MyApplication.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:viewmodel="using:MyApplication.ViewModel" xmlns:local="using:MyApplication"> <Application.Resources> <viewmodel:ViewModelLocator x:Key="Locator" /> </Application.Resources> </Application> <Page x:Class="MyApplication.View.MainPage" ... DataContext="{Binding Source={StaticResource Locator}, Path=Main}">
  • 11. NotifyPropertyChanged MVVM Light - v1.0 11 View Model public class Friend : ViewModelBase { private string _firstName = String.Empty; public string FirstName { get { return _firstName; } set { Set(() => this.FirstName, ref _firstName, value); } } private bool _isWorking = false; public bool IsWorking { get { return _isWorking; } set { Set(ref _isWorking, value); } }
  • 12. RelayCommand MVVM Light - v1.0 12 private RelayCommand<FriendItem> _displayDetailCommand; private void ExecuteDisplayDetailCommand(FriendItem item) { Messenger.Default.Send<FriendItem>(item); _navigationService.NavigateTo(ViewModel.ViewModelLocator.FRIENDDETAIL_PAGEKEY, item.ID); } private void ExecuteDisplayDetailCommand(FriendItem item) { Messenger.Default.Send<FriendItem>(item); _navigationService.NavigateTo(ViewModel.ViewModelLocator.FRIENDDETAIL_PAGEKEY, item.ID); } private bool CanExecuteDisplayDetailCommand(FriendItem item) { return true; }
  • 13. Navigation & Dialog MVVM Light - v1.0 13 View Model public class ViewModelLocator { public const string DAYDETAIL_PAGEKEY = "DayDetailPage"; static ViewModelLocator() { ... // NavigationService SimpleIoc.Default.Register<INavigationService>(() => { var navigationService = new Model.NavigationService(); navigationService.Configure(DAYDETAIL_PAGEKEY, typeof(View.DayDetailPage)); navigationService.Configure(SEARCH_PAGEKEY, typeof(View.SearchPage)); navigationService.Configure(TIMEDETAIL_PAGEKEY, typeof(View.TimeDetailView)); return navigationService; }); // DialogService SimpleIoc.Default.Register<IDialogService>(() => { return new DialogService(); }); ... } } navigation.NavigateTo(ViewModelLocator.DAYDETAIL_PAGEKEY, e.Date);
  • 14. View Model Navigation between ViewModels  In Source ViewModel ◦ Call NavigateTo method  In Target ViewModel ◦ Implement INavigableViewModel ◦ Override Page.OnNavigateTo MVVM Light - v1.0 14 public interface INavigableViewModel { void Activate(object parameter); void Deactivate(object parameter); } navigation.NavigateTo(ViewModelLocator.DAYDETAIL_PAGEKEY, e.Date); protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); var navigableViewModel = this.DataContext as Model.INavigableViewModel; if (navigableViewModel != null) navigableViewModel.Activate(e.Parameter); } protected override void OnNavigatedFrom(NavigationEventArgs e) { base.OnNavigatedFrom(e); var navigableViewModel = this.DataContext as Model.INavigableViewModel; if (navigableViewModel != null) navigableViewModel.Deactivate(e.Parameter); }
  • 15. Dialog from ViewModel  To display a dialog message, use DialogService registered in ViewModelLocator MVVM Light - v1.0 15 View Model await _dialogService.ShowMessage("Let's go to the friend detail.", "Title", "OK", () => { // This code will be executed after OK click. }); await _dialogService.ShowMessage("Continue?", "Title", "OK", "Cancel", (ok) => { if (ok) { _navigationService.NavigateTo(ViewModel.ViewModelLocator.FRIENDDETAIL_PAGEKEY, _selectedItem.ID); } });
  • 16. Async  CheckBeginInvokeOnUI MVVM Light - v1.0 16 View Model public async Task LoadDataAsync() { await Task.Run(async () => { var data = await _dataService.GetMyDataAsync(); DispatcherHelper.CheckBeginInvokeOnUI(() => { this.Items.AddRange(data); ... }); }); } public sealed partial class App : Application { protected override void OnLaunched(LaunchActivatedEventArgs e) { DispatcherHelper.Initialize(); ... InDesignMode, don’t user asynchronous tasks
  • 17. DataContext  From ViewModel Locator ◦ If constructor of ViewModel use only IoC parameters. MVVM Light - v1.0 17 View <Page x:Class="MyApplication.View.MainPage" ... DataContext="{Binding Path=Main, Source={StaticResource Locator}}"> public class MainViewModel : ViewModelBase { public MainViewModel(IDataService dataService, INavigationService navigationService) { ... } }
  • 18. DataContext  From Designer Creator ◦ If IoC Locator can not find the correct constructor MVVM Light - v1.0 18 View #if DEBUG /// <summary> /// This constructor is used in the Windows Phone app at design time, /// for the Blend visual designer. /// </summary> public DetailViewModel() : this(SimpleIoc.Default.GetInstance<Model.IDataService>(), SimpleIoc.Default.GetInstance<INavigationService>(), 0) { ... } #endif <Page x:Class="MyApplication.View.DetailPage" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" ... xmlns:vm="using:MyApplication.ViewModel" d:DataContext="{d:DesignInstance Type=vm:DetailViewModel, IsDesignTimeCreatable=True}"> public DetailViewModel(IDataService dataService, INavigationService navigationService, int id) { ...
  • 20. Design Mode  Drawing UI with Visual Studio (Blend) MVVM Light - v1.0 20
  • 21. DataService  DesignDataService MVVM Light - v1.0 21 public class DesignDataService : IDataService { private List<Friend> _friends = new List<Friend>(); public DesignDataService() { _friends.Add(new Friend() { LastName = "Voituron", FirstName = "Denis", ... }); _friends.Add(new Friend() { LastName = "Dubois", FirstName = "Anne", ... }); ... } } Model
  • 22. Navigation  DesignNavigationService MVVM Light - v1.0 22 public class DesignNavigationService : INavigationService { public string CurrentPageKey { get { Debug.WriteLine("DesignNavigationService.CurrentPageKey"); return String.Empty; } } public void GoBack() { Debug.WriteLine("DesignNavigationService.GoBack()"); } public void NavigateTo(string pageKey, object parameter) { Debug.WriteLine(String.Format("DesignNavigationService.NavigateTo("{0}", {1})", pageKey, parameter.ToString())); } public void NavigateTo(string pageKey) { Debug.WriteLine(String.Format("DesignNavigationService.NavigateTo("{0}")", pageKey)); } } Model
  • 23. Dialog  DesignDialogService MVVM Light - v1.0 23 public class DesignDialogService : IDialogService { public System.Threading.Tasks.Task ShowError(Exception error, string title, string buttonText, Action afterHideCallback) { throw new NotImplementedException(); } public System.Threading.Tasks.Task ShowError(string message, string title, string buttonText, Action afterHideCallback) { throw new NotImplementedException(); } ... } Model
  • 24. ViewModelLocator MVVM Light - v1.0 24 public class ViewModelLocator { static ViewModelLocator() { if (ViewModelBase.IsInDesignModeStatic) { DispatcherHelper.Initialize(); // DataService, Navigation and Dialog SimpleIoc.Default.Register<IDataService>(() => new DesignDataService()); SimpleIoc.Default.Register<INavigationService>(() => new DesignNavigationService()); SimpleIoc.Default.Register<IDialogService>(() => new DesignDialogService()); // ViewModels SimpleIoc.Default.Register<FriendViewModel>(); } else { } } } View Model
  • 26. Objectives  Define a manageable structure  Create Design data to draw UI easier  Create a DataService class to centralize all external requests  Use always asynchronous operations  Display a working progress bar MVVM Light - v1.0 26
  • 27. Universal project  Create Blank App (Universal App)  Add NuGet Packages for Solution  Select MVVM Light Libraries Only (PCL) ◦ WPF4.5 (and 4.5.1) ◦ Windows Phone (Silverlight) 8 ◦ Windows Phone (Silverlight) 8.1 ◦ Windows Phone (RT) 8.1 ◦ Windows Store (RT) 8 and 8.1 ◦ Xamarin Android ◦ Xamarin iOS ◦ PCL (for class libraries) MVVM Light - v1.0 27
  • 29. Asynchronous  IDataServices  DesignDataService MVVM Light - v1.0 29 public interface IDataService { Task<Friend[]> GetFriendsAsync(); } public class DesignDataService : Model.IDataService { List<Model.Friend> _friends = new List<Model.Friend>(); public DesignDataService() { _friends.Add(new Model.Friend() { FriendID = 1, LastName = "Voituron", ... _friends.Add(new Model.Friend() { FriendID = 2, LastName = "Dubois", ... } #pragma warning disable 1998 // Supress warning "This async method lacks 'await' op." public async Task<Model.Friend[]> GetFriendsAsync() { return _friends.ToArray(); } #pragma warning restore 1998 }
  • 30. Asynchronous  ViewModel MVVM Light - v1.0 30 public async void LoadDataAsync() { this.IsWorking = true; if (this.IsInDesignMode) { var data = await _dataService.GetFriendsAsync(); this.Friends.AddRange(data); return; } else { await Task.Run(async () => { var data = await _dataService.GetFriendsAsync(); DispatcherHelper.CheckBeginInvokeOnUI(() => { this.Friends.AddRange(data); }); }); } this.IsWorking = false; }
  • 32. References  http://www.mvvmlight.net/doc  http://www.spikie.be/blog/post/2013/04/12/10- things-you-might-have-missed-about-MVVM- Light.aspx  http://developer.nokia.com/community/wiki/How_to _use_MVVM_Light_Toolkit_for_Windows_Phone  https://marcominerva.wordpress.com  https://github.com/dvoituron/SampleMvvmLight MVVM Light - v1.0 32