Professional Documents
Culture Documents
Course Topics
Building Apps for Both Windows 8 and Windows Phone 8 Jump Start 01 | Comparing Windows 8 and Windows Phone 8 02 | Basics of View Models 03 | MVVM ( (Model-View-ViewModel) 04 | Sharing Code
Model-View-ViewModel
Agenda
Introduction to MVVM (ModelView-ViewModel)
Architecture
Pros and cons
MVVM libraries
MVVM Light Toolkit
Q&A
Introduction to MVVM
Architecture
View
Data Binding
Commands
View
Events /Messages
ViewModel
Messages, Callbacks
ViewModel
Model
Pros
Can reuse Model and View-Model code across platforms
Cons
Lots of boilerplate code May be more powerful than necessary for certain apps Decoupling loses strong type checking
Can show design-time data in Expression Blend and the Visual Studio designer
Commands
Messages
Model
The Model, or the Data Model, stores the persistent data for an app
Can be databases, local storage files, settings, or any other persistent data
Model should know nothing about the View or ViewModel Usually the most portable part of the app Windows Phone 8 supports a local SQL Server CE database
Windows 8 does not, but SQLite libraries are readily available
Model
public class CommonDataItem { public DataItem(string uid) { Uid = uid; } public string Uid { get; private set; } // Other properties ... } public interface IDataService { void GetItem(Action<CommonDataItem> callback, string uid); } public class DataService : IDataService { public void GetItem(Action<CommonDataItem> callback, string uid) { // Retrieve the data from the actual source // ... var item = new DataItem(...); callback(item); } }
View
A View should present the user with an interface to see and manipulate the data
An app can have many Views Views are defined by XAML
ViewModel
A ViewModel, or PresentationModel, is responsible for:
Presenting data to the view Responding to user manipulations of the view
Data binding can relieve the work of updating the view The ViewModel holds the business logic of the app Decoupled from the View
Lets developers work on the ViewModel while designers work on the View
ViewModel
An app can have many ViewModels
Usually a one-to-one correspondence between Views and ViewModels A ViewModel is linked to a View by setting the DataContext property for an element in the View
This binding is inherited by all child elements
ViewModel
public class MainViewModel : ViewModelBase { private readonly IDataService _dataService; public const string Title_PropertyName = "Title"; private string _title = string.Empty; public string Title { get { return _title; } set { if (_title == value) return; _title = value; RaisePropertyChanged(Title_PropertyName); } } // Constructor... } public MainViewModel(IDataService dataService) { _dataService = dataService; _dataService.GetData( (item) => { Title = item.Title; }); }
PhotoManager.Win8 PhotoManager.Core.Win8
PhotoManager.WP8 PhotoManager.Core.WP8
Shared
Demo: MVVM
Data Binding
Data binding is critical to the MVVM pattern
Advantages:
Write less code to update the view Easier to unit test Loose coupling avoids crashing the app Can provide design-time data for the designer
Commands
In MVVM, commands let the View tell the ViewModel to execute code in response to a user action
Replaces the paradigm of registering for events in the View. Implement System.Windows.Input.ICommand interface Commands can be enabled and disabled - Raise the CanExecuteChanged event when this happens
Commands
class AddItemCommand : ICommand { ViewModel _viewModel; public AddItemCommand(ViewModel viewModel) { _viewModel = viewModel; } public event EventHandler CanExecuteChanged; public bool CanExecute(object parameter) { return true; } public void Execute(object title) { _viewModel.AddItem(title as string); } }
In the XAML snippet, make sure that the DataContext is set to an instance of the ViewModel class. The ViewModel class exposes an AddCommand property of type AddItemCommand The ViewModel is responsible for actually adding a new item
Messages
Messages are a way to send information between objects.
Sender and receiver Useful for communication between ViewModels Often a callback for when the receiver is done handling a message No built-in APIs, but some MVVM libraries provide support
Messages
public abstract class BaseViewModel : INotifyPropertyChanged { private IMessenger _messenger; public IMessenger Messenger { get { return _messenger; } set { if (_messenger != null) Unsubscribe(); _messenger = value; Subscribe(); } } protected virtual void Unsubscribe() { } protected virtual void Subscribe() { } protected void PublishMessage<TMessage>(TMessage message) { if (Messenger != null) Messenger.Publish<TMessage>(message); } // ...
public interface IMessenger { void Subscribe<TMessage>(Action<TMessage> handler); void Unsubscribe<TMessage>(Action<TMessage> handler); void Publish<TMessage>(TMessage message); }
Messages
public class MessageRecipient { public MessageRecipient() { Messenger.Default.Register<MyMessage>(this, async (msg) => { var dlg = new MessageDialog(msg.Content); await dlg.ShowAsync(); }); } } public class MyMessage : MessageBase { public string Content { get; set; } }
var _recipient = new MessageRecipient(); // ... Messenger.Default.Send<MyMessage>(new MyMessage() { Content = "Hello World!" });
Best Practices
Design apps for cross-platform portability
Use MVVM to help achieve this
Best Practices
Data binding should eliminate a lot of the code in the codebehind file
Some code-behind is OK, but look for ways to use data-binding and commands to replace this code.
Avoid binding the same large collection multiple times on the same XAML page
This applies to pivots as well. Avoid duplicate bindings to different pivot pages that are part of the same pivot.
Binding does incur both memory and CPU overhead, so be careful how much data is bound to a page.
Best Practices
Large collections bound to list controls should be virtualized
You can use the VirtualizingStackPanel in place of the StackPanel
You can narrow the scope of the bindings data context within the XAML document. For example:
A Car object exposes an Engine object through a property named CarEngine A Car exposed by the MyCar property (of the View Model) is the data context for a XAML element Child elements of that XAML element can change their data context to the CarEngine by setting it to MyCar.CarEngine.
MVVM Libraries
Recap
Recap
MVVM means Model-View-ViewModel
The Model stores the persistent data
The View presents the user with an interface to view and manipulate data
A ViewModel presents data to the view and responds to user actions
MVVM is a useful pattern for Windows Phone 8 (and Windows 8) that lets you reuse much of your app business logic
Avoid causing chaos in the ViewModel when you replace the View
Q&A