-
The MVVM pattern – The practice
Let’s continue our journey to learn the MVVM pattern, applied to Universal Windows apps development. After we’ve learned the basic concepts in the previous post, now it’s time to start writing some code. As already mentioned in the previous post, we’re going to leverage MVVM Light as toolkit to help us implementing the pattern: since it’s the most flexible and simple to use, it will be easier to understand and apply the basic concepts we’ve learned so far.
The project
The goal of the MVVM pattern is to help developers to organize their code in a better way. As such, the first step is to define the structure of a project in a way that, also from a logical point of view, it can follow the principles of the pattern. Consequently, usually the first thing to do is to create a set of folders where to place our classes and files, like:
- Models, where to store all our basic entities.
- ViewModels, where to store the classes that will connect the Model with the View.
- Views, where to store the Views, which are the XAML pages in case of a Universal Windows app.
In a typical MVVM project, however, you will end up to have more folders: one of the assets, one for the services, one for the helper classes, etc.
The second step is to install in the project the library we have chosen to help us implementing the pattern. In our case, we chose MVVM Light, so we can leverage NuGet to install it. We will find two different versions:
- The complete package (http://www.nuget.org/packages/MvvmLight/) which, other than the libraries, it adds alse some documentation and a series of default classes (like a ViewModel, a ViewModelLocator, etc.)
- Just the libraries (http://www.nuget.org/packages/MvvmLightLibs/) which will add just the required DLLs.
For the moment, my suggestion is to use the second package: this way, we will do everything from scratch, giving us the chance to better learn the basic concepts. In the future, you’re free to use the first package if you want to save some time.
As a sample project, we’re going to create a very simple Universal Windows app that it’s likely you would be able to develop in no time using code behind: a Hello World app with a TextBox, where to insert your name, and a Button that, when it’s pressed, will display a hello message followed by your name.
Linking the View and ViewModel
The first step is to identify the three components of our application: Model, View and ViewModel.
- The model isn’t necessary in this application, since we don’t need to manipulate any entity.
- The view will be made by a single page, which will show to the user the TextBox where to insert his name and the Button to show the message.
- The ViewModel will be a class, which will handle the interaction in the view: it will retrieve the name filled by the user, it will compose the hello message and it will display it in the page.
Let’s start to add the various components: let’s create a Views folder and add, inside it, the only page of our application. As default behavior, when you create a new Universal Windows app the template will create a default page for you, called MainPage.xaml. You can move it to the Views folder or delete it and create a new one in Solution Explorer by right clicking on the folder and choosing Add –> New item –> Blank page.
Now let’s create the ViewModel that will be connected to this page. As explained in the previous post, the ViewModel is just a simple class: create a ViewModels folder, right click on it and choose Add –> New Item –> Class.
Now we need to connect the View and the ViewModel, by leveraging the DataContext property. In the previous post, in fact, we’ve learned that the ViewModel class is set as DataContext of the page; this way, all the controls in the XAML page will be able to access to all the properties and commands declared in the ViewModel. There are various ways to achieve our goal, let’s see them.
####
Declare the ViewModels as resources
Let’s say that you have created a ViewModel called MainViewModel. You’ll be able to declare it as a global resource in the App.xaml file this way:
<Application x:Class="MVVMSample.MVVMLight.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:viewModel="using:MVVMSample.MVVMLight.ViewModel"> <Application.Resources> <viewModel:MainViewModel x:Key="MainViewModel" /> </Application.Resources> </Application>
The first step is to declare, as attribute of the Application class, the namespace which contains the ViewModel (in this sample, it’s MVVMSample.MVVMLight.ViewModel). Then, in the Resources collection of the Application class, we declare a new resource which type is MainViewModel and we associate it to a key with the same name. Now we can use this key and the StaticResource keyword to connect the DataContext of the page to the the resource, like in the following sample:
<Page x:Class="MVVMSample.MVVMLight.Views.MainPage" DataContext="{Binding Source={StaticResource MainViewModel}}" mc:Ignorable="d"> <!-- your page content --> </Page>
The ViewModelLocator approach
Another frequently used approach is to leverage a class called ViewModelLocator, which has the responsability of dispatching the ViewModels to the various pages. Instead of registering all the ViewModels as global resources of the application, like in the previous approach, we register just the ViewModelLocator. All the ViewModels will be exposed, as properties, by the locator, which will be leveraged by the DataContext property of the page.
This is a sample definition of a ViewModelLocator class:
public class ViewModelLocator { public ViewModelLocator() { } public MainViewModel Main { get { return new MainViewModel(); } } }
Or, as an alternative, you can simplify the code by leveraging one of the new C# 6 .0 features:
public class ViewModelLocator { public ViewModelLocator() { } public MainViewModel Main => new MainViewModel(); }
After you’ve added the ViewModelLocator class as global resource, you’ll be able to use it to connect the Main property to the DataContext property of the page, like in the following sample:
<Page x:Class="MVVMSample.MVVMLight.Views.MainPage" DataContext="{Binding Source={StaticResource Locator}, Path=Main}" mc:Ignorable="d"> <!-- your page content --> </Page>
The syntax is very similar to the one we’ve seen with the first approach; the main difference is that, since the ViewModelLocator class can expose multiple properties, we need to specify with the Path attribute which one we want to use.
The ViewModelLocator’s approach adds a new class to maintain, but it gives you the flexibilty to handle the ViewModel’s creation in case we need to pass some parameters to the class’ constructor. In the next post, when we’ll introduce the dependeny injection’s concept, it will be easier for you to understand the advantages in using the ViewModelLocator approach.
Let’s setup the ViewModel
No matter which approach we decided to use in the previous step, now we have a View (the page that will show the form to the user) connected to a ViewModel (the class that will handle the user’s interactions).
Let’s start to populate the ViewModel and to define the properties that we need to reach our goal. In the previous post we’ve learned that ViewModels need to leverage the INotifyPropertyChanged interface; otherwise, every time we change the value of a property in the ViewModel, the View won’t be able to detect it and the user won’t see any change in the user interface.
To make easier to implement this interface, MVVM Light offers a base class which we can leverage in our ViewModels using inheritance, like in the following sample:
public class MainViewModel : ViewModelBase { }
This class gives us access to a method called Set(), which we can use when we define our propeties to dispatch the notifications to the user interface when the value changes. Let’s see a sample related to our scenario. Our ViewModel has to be able to collect the name that the user has filled into a TextBox control in the View. Consequently, we need a property in our ViewModel to store this value. Here is how it looks like thanks to the MVVM Light support:
private string _name; public string Name { get { return _name; } set { Set(ref _name, value); } }
The code is very similar to the one we’ve seen in the previous post when we introduced the concept of the INotifyPropertyChanged interface. The only difference is that, thanks to the Set() method, we can achieve two goals at the same time: storing the value in the Name property and dispatching a notification to the binding channel that the value has changed.
Now that we have learned how to create properties, let’s create another one to store the message that we will display to the user after he has pressed the button.
private string _message; public string Message { get { return _message; } set { Set(ref _message, value); } }
In the end, we need to handle the interaction with the user. When he presses the Button in the view, we have to display a hello message. From a logical point of view, this means:
- Retrieving the value of the Name property.
- Leveraging the string interpolation APIs to prepare the message (something like “Hello Matteo”).
- Assign the result to the Message property.
In the previous post we’ve learned that, in the MVVM pattern, you use commands to handle the user interactions in a ViewModel. As such, we’re going to use another one of the classes offered by MVVM Light, which is RelayCommand. Thanks to this class, instead of having to create a new class that implements the ICommand interface for each command, we can just declare a new one with the following code:
private RelayCommand _sayHello; public RelayCommand SayHello { get { if (_sayHello == null) { _sayHello = new RelayCommand(() => { Message = $"Hello {Name}"; }); } return _sayHello; } }
When you create a new RelayCommand object you have to pass, as parameter, an Action, which defines the code that you want to execute when the command is invoked. The previous sample declares an Action using an anonymous method. It means that, instead of defining a new method in the class with a specific name, we define it inline in the property definition, without assigning a name.
When the command is invoked, we use the new C# 6.0 feature to perform string interpolation to get the value of the property Name and add the prefix “Hello”. The result is stored into the Message property.
###
###
Create the view
Now that the ViewModel is ready, we can move on and create the View. The previous step should have helped you to understand one of the biggest benefits of the MVVM pattern: we’ve been able to define the ViewModel to handle the logic and the user interaction without writing a single line of code in the XAML file. With the code behind approach, it would have been impossible; for example, if we wanted to retrieve the name filled in the TextBox property, we should have first added the control in the page and assign to it a name using the x:Name property, so that we would have been able to access to it from code behind. Or if we wanted to define the method to execute when the button is pressed, we would have needed to add the Button control in the page and subscribe to the Click event.
From a user interface point of view, the XAML we need to write for our application is more or less the same we would have created for a code behind app. The UI, in fact, doesn’t have any connection with the logic, so the way we create the layout doesn’t change when we use the MVVM pattern. The main difference is that, in a MVVM app, we will use binding a lot more, since it’s the way we can connect the controls with the properties in the ViewModel. Here is how our View looks like:
<Page x:Class="MVVMSample.MVVMLight.Views.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" DataContext="{Binding Source={StaticResource Locator}, Path=Main}" mc:Ignorable="d"> <Grid> <StackPanel Margin="12, 30, 0, 0"> <StackPanel Orientation="Horizontal" Margin="0, 0, 0, 30"> <TextBox Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="300" Margin="0, 0, 20, 0" /> <Button Command="{Binding Path=SayHello}" Content="Click me!" /> </StackPanel> <TextBlock Text="{Binding Path=Message}" Style="{StaticResource HeaderTextBlockStyle}" /> </StackPanel> </Grid> </Page>
We have added to the page three controls:
- A TextBox, where the user can fill his name. We have connected it to the Name property of the ViewModel. There are two features to higlight:
- We have set the Mode attribute to TwoWay. It’s required since, for this scenario, we don’t just need that when the property in the ViewModel changes the control displays the updated value, but also the opposite. When the user fills some text in the control, we need to store its value in the ViewModel.
- We have set the UpdateSourceTrigger attribute to PropertyChanged. This way, we make sure that, every time the text changes (which means every time the user adds or remove a char in the TextBox), the Name property will automatically update to store the changed value. Without this attribute, the value of the property would be updated only when the TextBox control loses the focus.
- A Button, that the user will click to see the hello message. We have connected it to the SayHello command in the ViewModel.
- A TextBlock, where the user will see the hello message. We have connected it to the Message property of the ViewModel.
If we have done everything properly and we launch the app, we should see the application behaving as we described at the beginning of this post: after filling your name and pressing the button, you will see the hello message.
###
Let’s improve the user interaction
Our application has a flaw: if the user presses the button without writing anything in the TextBox, he would see just the “Hello” prefix. We want to avoid this behaviro by disabling the button if the TextBox control is empty. To achieve our goal we can leverage one of the features offered by the ICommand interface: we can define when a command should be enabled or not. For this scenario the RelayCommand class allows a second parameter during the initialization, which is a function that returns a boolean value. Let’s see the sample:
private RelayCommand _sayHello; public RelayCommand SayHello { get { if (_sayHello == null) { _sayHello = new RelayCommand(() => { Message = $"Hello {Name}"; }, () => !string.IsNullOrEmpty(Name)); } return _sayHello; } }
We’ve changed the initialization of the SayHello command to add, as a second parameter, a boolean value: specifically, we check if the Name property is null or empty (in this case, we return false, otherwise true). Thanks to this change, now the Button control connected to this command will be automatically disabled (also from a visual point of view) if the Name property is empty. However, there’s a catch: if we try the application as it is, we would notice that the Button will be disabled by default when the app starts. It’s the expected behavior, since when the app is launched the TextBox control is emtpy by default. However, if we start writing something in the TextBox, the Button will continue to be disabled. The reason is that the ViewModel isn’t able to automatically determine when the execution of the SayHello command needs to be evaluated again. We need to do it manually every time we do something that may change the value of the boolean function; in our case, it happens when we change the value of the Name property, so we need to change the property definition like in the following sample:
private string _name; public string Name { get { return _name; } set { Set(ref _name, value); SayHello.RaiseCanExecuteChanged(); } }
Other than just using the Set() method to store the property and to send the notification to the user interface, we invoke the RaiseCanExecuteChanged() method of the SayHello command. This way, the boolean condition will be evaluated again: if the Name property contains some text, than the command will be enabled; otherwise, if it should become empty again, the command will be disabled.
In the next post
In this post we’ve finally started to apply with a real project the concepts we’ve learned in the first post and we have started to write our first application based on the MVVM pattern. In the next posts we’ll see some advanced scenario, like dependency injection, messages or how to handle secondary events. Meanwhile, you can play with the sample app we’ve created in this post, which is published on my GitHub repository https://github.com/qmatteoq/UWP-MVVMSamples. Together with the sample created in this post, you will find also the same sample created using Caliburn Micro as MVVM framework instead of MVVM Light. Happy coding!
Introduction to MVVM – The series
in
-
The MVVM pattern – Introduction
Model-View-ViewModel (from now on, just MVVM) is a “love and hate” topic when it comes to Universal Windows app development. If you have never used it and you try it for the first time, you’ll probably find yourself a little bit confused, since it’s a completely different approach than the standard one based on the code behind. On the other side, if you’re a long time MVVM user, probably you won’t be able anymore to create a new project using any other approach. This is the reason why I’ve decided to write the following series of posts: what’s MVVM? Why is it so widely adpoted when it comes to Universal Windows apps development and, generally speaking, by any XAML based technology? I hope that, at the end of the journey, you’ll find an answer to all your questions and you’ll be able to start using the MVVM pattern in your apps without being scared anymore
###
The MVVM pattern
The first thing you have to understand is that MVVM isn’t a framework or a library, but a pattern: it isn’t a set of APIs or methods, but a way to define the architecture of an application. Probably you’ve already heard about MVVM LIght or Caliburn Micro, but you don’t have to confuse them with MVVM: they’re tools that helps developers to adopt the MVVM pattern, they don’t represent the pattern itself.
The purpose of a pattern is to help developers to define the architecture of an application. Why is so important to do it? Why we cant’t simply continue to develop an application in the way we are used to, which is writing all the code in the code-behind class? The standard approach is very quick and simple to understand but it has many limitations when it comes to more complex projects, that needs to be maintained over time. The reason is that the code-behind class has a very tight dependency with the XAML page. Consequently, most of the code can’t be isolated and we end up to mix business logic and the presentation layer.
In the long run, the code behind approach introduces many problems:
- It’s more complicated to maintain the code and evolve the project. Every time we need to add a new feature or solve a bug, it’s hard to understand where precisely we need to it, since there isn’t a clear distinction between the various components of the app. This becomes even more true if we need to resume working on a project which has been “on hold” for a long time.
- It’s complex to perform unit testing. When it comes to complex projects, many developers and companies are adopting the unit test approach, which is a way to perform automatic tests that validate small pieces of code. This way it becomes easier to evolve the project: every time we add a new feature or we change some existing code, we can easily verify if the work we’ve done has broken the already existing features of the app. However, having a tight dependency between the logic and the user interface makes nearly impossible to write unit tests, since the code isn’t isolated.
- It’s complex to design the user interface: since there’s a tight relationship between the user interface and the business logic, it isn’t possible for a designer to focus on the user interface without knowing all the implementation details behind it. Questions like “where the data is coming from? A database? A cloud service?” shouldn’t be asked by a designer.
The goal of the MVVM pattern is to “break” this strong connection between the code behind and the user interface, making easier for a developer to understand which are the different components of the application. More precisely, it’s fundamental to distinguish the components which take care of the business logic and the ones that handle the data presentation.
The name of the pattern comes from the fact that the project is split into three different components, which now we’re going to explore in details.
###
The model
The model is the component of the application that defines and handles all the basic entities of the application. The goal of this layer is to remove any dependency from the way the data is represented. Ideally, you should be able to take the classes that belong to this component and use them in another application without applying any change. For example, if you’re working on an application to handle orders and customers of a company, the model could be defined by all the classes which define the base entities, like a customer, an order, a product, etc.
The view
The view is at the opposite side of the model and it’s represented by the user inteface. In the Universal Windows apps world, views are made by the XAML pages, which contain all the controls and animations that define the visual layout of the application. Recyicling the already mentioned sample of an app to handle orders and customers, we can have multiple views to display the list of customers, the available products in the warehouse, the orders made by a customer, etc.
The ViewModel
The ViewModel is the connection point between the view and model: it takes care of retrieving the raw data from the model and to manipulate it so that it can be properly displayed by the view. The huge difference with a code behind class is that the ViewModel is just a plain simple class, without any dependency from the View. In an application based on the MVVM pattern, typically you create a ViewModel for every View.
###
###
Why the MVVM pattern?
After this brief introduction, it should be easier to understand why the MVVM pattern is so important and how, by adopting it, we can solve all the problems mentioned at the beginning of the post.
- By splitting the code in three different layers it becomes easier, especially if you’re working in a team, to maintain and evolve the application. If you need to add a feature or to solve a bug, it’s easier to identify which layer has to be manipulated. Moreover, since there is no dependency between each layer, the work can be also done in parallel (for example, a designer can start working on the user interface while another developer can create the services which will be used by the page to retrieve the data).
- To properly perform unit testing, the code to test has to be as simple and isolated as possible. When you work with the code-behind approach, this is simply not possible: often the logic is connected to an event handler (for example, because the code has to be executed when you press a button) and you would need to find a way to simulate the event in order to trigger the code to test. By adopting the MVVM pattern we break this tight dependency: the code included in a ViewModel can be easily isolated and tested.
- Since we have broken the tight connection between the user interface and the business logic, for a designer it’s easy to define the interface without having to know all the implementation details of the application. For example, if the designer has to work on a new page which displays a list of orders, we can easily swap the real ViewModel (which retrieves the data from a real data source, like a cloud service or a database) with a fake one, which can generate fake data that allows to the designer to easily understand which kind of information the page should display.
Why in the Universal Windows app world most of the developers tend to use the MVVM pattern and not other popular patterns like MVC or MVP? Mainly, because the MVVM pattern is based on many features which are at the core of the XAML runtime, like binding, dependency properties, etc. In this series of post we’re going to talk a bit more about these features. You can notice how I’ve just mentioned XAML runtime and not the Universal Windows Platform: the reason is that most of the things we’re going to see in these posts aren’t specific of the Universal Windows app world, but they can be applied to any XAML based technology, like WPF, Silverlight, Windows Phone, Xamarin, etc.
Let’s see now, in details, which are the basic XAML features leveraged by the MVVM pattern.
###
###
The binding
Binding is one of the most important XAML features and allows to create a communication channel between two different properties. They can be properties that belong to different XAML controls, or a property declared in code with a control’s property. The key feature leveraged by the MVVM pattern is the second one: View and ViewModels are connected thanks to binding. The ViewModel takes care of exposing the data to show in the View as properties, which will be connected to the controls that will display them using binding. Let’s say, for example, that we have a page in the application that displays a list of products. The ViewModel will take care of retrieving this information (for example, from a local database) and to store it into a specific property (like a collection of type **List
**): public List<Order> Orders { get; set; }
To display the collection in a traditional code behind app, at some point, you would manually assign this property to the ItemsSource property of a control like ListView or GridView, like in the following sample:
MyList.ItemsSource = Orders;
However, this code creates a tight connection between the logic and the UI: since we’re accessing to the ItemsSource property using the name of the control, we can perform this operation only in the code behind class.
With the MVVM pattern, instead, we connect properties in the ViewModel with controls in the UI using binding, like in the following sample:
<ListView ItemsSource="{Binding Path=Orders}" />
This way, we have broken the dependency between the user interface and the logic, since the Orders property can be defined also in a plain simple class like a ViewModel.
As already mentioned, binding can be also bidirectional: this approach is used when not just the ViewModel needs to display some data in the View, but also the View should be able to change the value of one of the ViewModel’s properties. Let’s say that your application has a page where he can create a new order and, consequently, it includes a TextBox control where to set the name of the product. This information needs to be handled by the ViewModel, since it will take care of interacting with the model and adding the order to the database. In this case, we apply to the binding the Mode attribute and we set it to TwoWay, so that everytime the user adds some text to the TextBox control, the connected property in the ViewModel will get the inserted value.
If, in the XAML, we have the following code, for example:
<TextBox Text="{Binding Path=ProductName, Mode=TwoWay}" />
it means that in the ViewModel we will have a property called ProductName, which will hold the text inserted by the user in the box.
The DataContext
In the previous section we’ve seen how, thanks to the binding, we are able to connect the ViewModel’s properties to the controls in the XAML page. You may be wondering how the View model is able to understand which is the ViewModel that populates its data. To understand it, we need to introduce the DataContext’s concept, which is a property offered by any XAML Control. The DataContext property defines the binding context: every time we set a class as a control’s DataContext, we are able to access to all its public properties. Moreover, the DataContext is hierarchical: properties can be accessed not only by the control itself, but also all the children controls will be able to access to them.
The core of the implementation of the MVVM pattern relies on this hierarachy: the class that we create as ViewModel of a View is defined as DataContext of the entire page. Consequently, every control we place in the XAML page will be able to access to the ViewModel’s properties and show or handle the various information. In an application developed with the MVVM pattern, usually, you end up to have a page declaration like the following one:
<Page x:Class="Sample.MainPage" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" DataContext="{Binding Source={StaticResource MainViewModel}}" mc:Ignorable="d"> <!-- page content goes here --> </Page>
The DataContext property of the Page class has been connected to a new instance of the MainViewModel class.
The INotifyPropertyChanged interface
If we try to create a simple application based on the MVVM pattern applying the concepts we’ve learned so far, we would quickly hit a big issue. Let’s use the previous sample of the page to add a new order and let’s say that we have, in the ViewModel, a property which we use to display the product’s name, like the following one:
public string ProductName { get; set; }
According to what we have just learned, we expect to have a TextBlock control in the page to display the value of this property, like in the following sample:
<TextBlock Text="{Binding Path=ProductName}" />
Now let’s say that, during the excecution of the app, the value of the ProductName proeprty changes (for example, because a data loading operation is terminated). We will notice how, despite the fact that the ViewModel will properly hold the new value of the property, the TextBlock control will continue to show the old one. The reason is that binding isn’t enough to handle the connection between the View and the ViewModel. Binding has created a channel between the ProductName property and the TextBlock, but no one notified both sides of the channel that the value of the property has changed. For this purpose, XAML offers the concept of dependency properties, which are special properties that can define a complex behavior and, under the hood, are able to send a notification to both sides of the binding channel every time its value changes. Most of the basic XAML controls use dependency properties (for example, the Text property of the TextBlock control is a dependency property). However, defining a new dependency property isn’t very straightforward and, in most of the cases, it offers features which aren’t needed for our MVVM scenario. Let’s take the previous sample based on the ProductName property: we don’t need to handle any special behavior or logic, we just need that, every time the ProductName property changes, both sides of the binding channel receive a notification, so that the TextBlock control can update its visual layout to display the new value.
For these scenarios, XAML offers a specific interface called INotifyPropertyChanged, which we can implement in our ViewModels. This way, if we need to notify the UI when we change the value of a property, we don’t need to create a complex dependency property, but we just need to implement this interface and invoke the related method every time the value of the property changes.
Here is how a ViewModel that implements this interface looks like:
public class MainViewModel: INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
You can notice how the implementation of this interface allows us to call a method called OnPropertyChanged(), that we can invoke every time the value of a property changes. However, to reach this goal, we need to change the way how we define the properties inside our ViewModel. When it comes to simple properties, usually we define them using the short syntax:
public string ProductName { get; set; }
Hower, with this syntax we can’t change what happens when the value of the property is written or read. As such, we need to go back to use the old approach, based on a private variable which holds the value of the property. This way, when the value is written, we are able to invoke the OnPropertyChanged() method and dispatch the notification. Here is how a property in a ViewModel looks like:
private string _productName; public string ProductName { get { return _productName; } set { _productName = value; OnPropertyChanged(); } }
Now the property will work as expected: when we change its value, the TextBlock control in binding with it will change his appearance to display it.
###
Commands (or how to handle events in MVVM)
Another critical scenario when it comes to develop an application is to handle the interactions with the user: he could press a button, choose an item in a list, etc. In XAML, these scenarios are handled using events which are exposed by various controls. For example, if you want to handle that the button has been pressed, we need to subscribe to the Click event, like in the following sample:
<Button Content="Click me" Click="OnButtonClicked" />
The event is managed by an event handler, which is a method that includes, among the various parameters, some information which are useful to understand the event context (for example, the control which triggered the event or which item of the list has been selected), like in the following sample:
private void OnButtonClicked(object sender, RoutedEventArgs e) { //do something }
The problem of this approach is that event handlers have a tight dependency with the View: they can be declared, in fact, only in the code behind class. When you create an application using the MVVM pattern, instead, all the data and logic is usually defined in the ViewModel, so we need to find a way to handle the user interaction there.
For this purpose, the XAML has introduced commands, which is a way to express a user interaction with a property instead that with an event handler. Since it’s just a simple property, we can break the tight connection between the view and the event handler and we can define it also in an independent class, like a ViewModel.
The framework offers the ICommand interface to implement commands: with the standard approach, you end up having a separated class for each command. The following example shows how a command looks like:
public class ClickCommand : ICommand { public bool CanExecute(object parameter) { } public void Execute(object parameter) { } public event EventHandler CanExecuteChanged; }
The core of the command is the Execute() method, which contains the code that is executed when the command is invoked (for example, because the user has pressed a button). It’s the code that, in a traditional application, we would have written inside the event handler.
The CanExecute() method is one of the most interesting features provided by commands, since it can be used to handle the command’s lifecycle when the app is running. For example, let’s say that you have a page with a form to fill, with a button at the end of the page that the user has to press to send the form. Since all the fields are required, we want to disable the button until all the fields have been filled. If we handle the operation to send the form with a command, we are able to implement the CanExecute() method in a way that it will return false when there’s at least one field still empty. This way, the Button control that we have linked to the command will automatically change his visual status: it will be disabled and the user will immediately understand that he won’t be able to press it.
In the end, the command offers an event called CanExecuteChanged, which we can invoke inside the ViewModel every time the condition we want to monitor to handle the status of the command changes. For example, in the previous sample, we would call the CanExecuteChanged event every time the user fills one of the fields of the form.
Once we have define a command, we can link it to the XAML thanks to the Command property, which is exposed by every control that are able to handle the interaction with the user (like Button, RadioButton, etc.)
<Button Content="Click me" Command="{Binding Path=ClickCommand}" />
As we’re going to see in the next post, however, most of the toolkits and frameworks to implement the MVVM pattern offers an easier way to define a command, without forcing the developer to create a new class for each command of the application. For example, the popular MVVM Light toolkit offers a class called RelayCommand, which can be used to define a command in the following way:
private RelayCommand _sayHello; public RelayCommand SayHello { get { if (_sayHello == null) { _sayHello = new RelayCommand(() => { Message = string.Format("Hello {0}", Name); }, () => !string.IsNullOrEmpty(Name)); } return _sayHello; } }
As you can see, we don’t need to define a new class for each command but, by using anonymous methods, we can simply create a new RelayCommand object and pass, as parameters:
- The code that we want to excecute when the command is invoked.
- The code that evaluates if the command is enabled or not.
We’re going to learn more about this approach in the next post.
###
How to implement the MVVM pattern: toolkits and frameworks
As I’ve mentioned at the beginning of the post, MVVM is a pattern, it isn’t a library or a framework. However, as we’ve learned up to now, when you create an application based on this pattern you need to leverage a set of standard procedures: implementing the INotifyPropertyChanged interface, handling commands, etc.
Consequently, many developers have started to work on libraries that can help the developer’s job, allowing them to focus on the development of the app itself, rather than on how to implement the pattern. Let’s see which are the most popular libraries.
####
####
MVVM Light
MVVM Light (http://www.mvvmlight.net) is a library created by Laurent Bugnion, a long time MVP and one of the most popular developers in the Microsoft world. This library is very popular thanks to its flexibility and simplicity. MVVM Light, in fact, offers just the basic tools to implement the pattern, like:
- A base class, which the ViewModel can inherit from, to get quick access to some basic features like notifications.
- A base class to handle commands.
- A basic messaging system, to handle the communication between different classes (like two ViewModels).
- A basic system to handle dependency injection, which is an alternative way to initialize ViewModels and handle their dependencies. We’ll learn more about this concept in another post.
Since MVVM Light is very basic, it can be leveraged not just by Universal Windows apps, but also in WPF, Sivlerlight and even Android and iOS thanks to its compatibility with Xamarin. Since it’s extremely flexible, it’s also easy to adapt it to your requirements and as a starting point for the customization you may want to create. This simplicity, however, is also the weakness of MVVM Light. As we’re going to see in the next posts, when you create a Universal Windows app using the MVVM pattern you will face many challenges, since many basic concepts and features of the platform (like the navigation between different pages) can be handled only in a code behind class. From this point of view, MVVM Light doesn’t help the developer that much: since it offers just the basic tools to implement the pattern, every thing else is up to the developer. For this reasons, you’ll find on the web many additional libraries (like the Cimbalino Toolkit) which extend MVVM Light and add a set of services and features that are useful when it comes to develop a Universal Windows app.
Caliburn Micro
Caliburn Micro (http://caliburnmicro.com) is a framework originally created by Rob Eisenberg and now maintained by Nigel Sampson and Thomas Ibel. If MVVM Light is a toolkit, Caliburn Micro is a complete framework, which offers a completely differnent approach. Compared to MVVM Light, in fact, Caliburn Micro offers a rich set of services and features which are specific to solve some of the challenges provided by the Universal Windows Platform, like navigation, storage, contracts, etc.
Caliburn Micro handles most of the basic features of the pattern with naming conventions: the implementation of binding, commands and others concepts are hidden by a set of rules, based on the names that we need to assign to the various components of the project. For example, if we want to connect a ViewModel’s property with a XAML control, we don’t have to manually define a binding: we can simply give to the control the same name of the property and Caliburn Micro will apply the binding for us. This is made possible by a boostrapper, which is a special class that replaces the standard App class and takes care of intializing, other than the app itself, the Caliburn infrastructure.
Caliburn Micro is, without any doubt, very powerful, since you’ll have immediate access to all the tools required to properly develop a Universl Windows app using the MVVM pattern. However, in my opinion, isn’t the best choice if you’re new to the MVVM pattern: since it hides most of the basic concepts which are at the core of the pattern, it can be complex for a new developer to understand what’s going on and how the different pieces of the app are connecte together.
Prism
Prism (http://github.com/PrismLibrary/Prism) is another popular framework which, in the beginning, was created and maintaned by the Pattern & Practises division by Microsoft. Now, instead, it has become a community project, maintained by a group of independent developers and Microsoft MVPs.
Prism is a framework and uses a similar approach to the one provided by Caliburn Micro: it offers naming convention, to connect the different pieces of the app together, and it includes a rich set of services to solve the challenges provded by the Universal Windows Platform.
We can say that it sits in the middle between MVVM Light and Caliburn Micro, when it comes to complexity: it isn’t simple and flexible like MVVM Light but, at the same time, it doesn’t use naming convention in an aggressive way like Caliburn Micro does.
Coming soon
In the next posts we’re going to turn what we’ve learned so far int oa realy project and we’re going to leverage MVVM Light for this purpose: the reason is that, as I’ve already mentioned, I think MVVM Light is the easiest one to understand, especially if you’re new to the pattern, since it will help us to learn all the basic concepts which are at the core of the pattern. If you want to start looking at a real project, you’ll find many samples (which we’re going to explain in a more detailed way) on my GitHub repository at https://github.com/qmatteoq/UWP-MVVMSamples. Stay tuned!
P.S.= this post has been written with OpenLiveWriter, the new open source version of Windows Live Writer, which has now become a community driven project. In my opinion (and not just mine ) Open Live Writer is the best tool in the world to write blog posts, so thanks to Microsoft for making this happen and thanks to all the great developers that are contributing to the project and keeping it alive!
Introduction to MVVM – The series
in
-
Template10: a new template to create Universal Windows apps – MVVM
The Model-View-ViewModel pattern (from now on, just MVVM) is, without any doubt, the most widely used pattern when it comes to develop XAML based applications. In this post, we won’t learn all the inner details of the pattern: I’ve already talked about it many times in this blog, when I presented some of the most popular MVVM frameworks like Caliburn Micro and Prism. The goal of the MVVM pattern is to improve testability and maintainability of an application, since it helps the developer in reaching one of the key goals that drives any complex development project: keeping the different layers separated, so that the code that handles the user interface doesn’t mix with the one that handles the business logic (like retrieving the data from the cloud or from a database).
The MVVM pattern is heavily used in the Universal Windows app world and, generally speaking, also in all the XAML based technologies, since it relies on the basic XAML feature like binding, dependency properties, the INotifyPropertyChanged interface, etc. When you use this pattern, you typically split the project into three components:
- The model, which are the entities and the services that are used to handle the raw data of the application, without dependencies on how they are presented.
- The view, which is the user interface presented to the user. In Universal Windows apps, the Views are identified with the XAML pages.
- The ViewModel, which is the connection between the view and the model. ViewModel are simple classes that takes care of retrieving the data handled by the model and of preparing them to be presented by the View using binding.</ol> The MVVM pattern gives to developers a lot of benefits but, however, it requires some time to be configured into a new project: the problem is that when you create a new Universal Windows app there are a lot of scenarios (navigation, the application’s lifecycle, contracts, etc.) which are simple to implement when you use code-behind, but that need to be reviewed when you use the MVVM pattern, since most of the code is written in a ViewModel, which is an independent class. A good example of this problem is the page lifecycle management: typically, in a Universal Windows app you use the OnNavigatedTo() and OnNavigatedFrom() events to handle the navigation from one page to another. However, these events are exposed only by the code behind class, since it inherits from the Page class; you can’t use them in a ViewModel, which doesn’t have any dependency from it.
For this reason, many developers have created libraries and frameworks which makes the developer’s life easier, by providing all the needed tools. The most popular ones are MVVM Light by Laurent Bugnion, Caliburn Micro by Rob Esieneberg and Prism, originally developed by the Microsoft Pattern & Practice division and now turned in to a community project. Every framework has its own pros and cons: MVVM Light is the simplest and most flexible one, but it lacks any helper to handle the typical scenarios of a Universal Windows app. Caliburn Micro and Prism, on the other side, are more complex to master and a little bit “rigid”, but they offer many tools to handle common scenarios like navigation, page lifecycle, etc.
Template10 doesn’t act as another MVVM framework (even if, as we’re going to see, it offers some classes to implement it without having to rely on another library), but it helps developers to make the implementation of the MVVM pattern easier. Let’s see in details which are these facilities: it’s important to remember that what we have described in the previous posts (bootstrapper, extended splash screen, the new controls, etc.) can be applied also on MVVM based projects.
The basic tools to implement the pattern
Even if Template10 doesn’t behave as a complete alternative to the existing libraries, it offers any way the basic tools required to implement it in the proper way. You aren’t forced to use them: you can choose, for example, to add MVVM Light to your project and to use its helpers in replacement of the ones that I’m going to describe.
The first important helper offered by Template10 is the ViewModelBase class, which is the base class which your ViewModels should inherit from. Other than offering a set of useful features that we’re going to see later in this post, it offers the basic tools to implement the pattern. The most important one is the Set() method, which can be used to propagate the changes to the ViewModel properties to the user interface, by implementing the INotifyPropertyChanged interface. Here is how you can use it to define a property in the ViewModel:
public class MainViewModel : Template10.Mvvm.ViewModelBase { public MainViewModel() {
- The view, which is the user interface presented to the user. In Universal Windows apps, the Views are identified with the XAML pages.
} private string _name; public string Name { get { return _name; } set { Set(ref _name, value); } } }
</pre>
The **Set()** method, invoked inside the property’s setter, allows to send a notification to the view that the value has changed, other than just effectively changing the value of the property. This way, if in the View you have one or more controls connected to this property through binding, they will update their visual state to reflect the changes. For example, here is how you can connect a **TextBlock** control placed in the XAML page to the property we’ve just declared: <pre class="brush: xml;"><TextBlock Text="{Binding Path=Name}" />
</pre>
If you already have some experience with MVVM Light, this approach will be familiar to you: also this toolkit offers a method called **Set()**, which has the same purpose. Another important feature that Template10 implements is the **DelegateCommand** class, which can be used to easily create commands. Which is the purpose of commands? When it comes to handle the user interaction in a traditional application created using the code-behind approach, you rely on **event handlers:** they’re methods that are connected to an event that is raised by a control, like pressing a button or selecting an item from a list. These event handlers have a tight dependency with the view and, as such, they can be declared only in the code-behind class. In a MVVM application, instead, most of the logic is handled by the ViewModel and, consequently, we would need to handle the user interaction in a ViewModel. This is exactly the purpose of commands: a way to handle an event using a property, so that we can connect it to a control using binding. This way, we can “break” the dependency that traditional event handlers have with the view and we can declare commands in any class, including ViewModels. A command is defined by: 1. The actions to perform when the command is invoked. * The condition that needs to be satisfied to enable the command. This feature is very useful, because it makes sure that the control connected to the command automatically changes his visual status based on the command status. For example, if a command is connected to a **Button** control and, during the execution, the command is disabled, also the button will be disabled: it will be displayed in grey and the user won’t be able to tap on it.</ol> The Windows Runtime offers a base class to implements commands, called **ICommand**: however, it’s just an interface, the concrete implementation is up to the developer, who would need to create a class for every command. To reduce the footprint and speed up the development, Template10 offers a class called **DelegateCommand**, which implements this interface and that can be initialized simply by passing to the constructor the two required information. Here is an example: <pre class="brush: csharp;">private DelegateCommand _setNameCommand;
public DelegateCommand SetNameCommand { get { if (_setNameCommand == null) { _setNameCommand = new DelegateCommand(() => { Result = $”Hello {Name}”; }, () => !string.IsNullOrEmpty(Name));
} return _setNameCommand; } }
</pre>
The first parameter is an **Action** (in this case, it’s defined using an anonymous method), which defines the operations to execute when the command is invoked. The second optional parameter, instead, is a function that should return a boolean value and that is used to determine if the command is enabled or not. In the sample, the command is enabled only in case the content of the **Name** property isn’t empty. Once you have defined a command, you can connect it to a XAML control using the property with the same name, which is exposed by all the controls that support the user interaction (like the **Button** control). The following sample shows how to use the **Command** property offered by the **Button** control to connect the **DelegateCommand** property we’ve previously defined. <pre class="brush: xml;"><Button Content="Click me" Command="{Binding Path=SetNameCommand}" />
</pre>
Also in this case, if you have previous experience with MVVM Light, the approach will be familiar: the toolkit, in fact, offers a class called **RelayCommand** for the same purpose and which works in the same way. ### ### Navigation and page’s lifecycle We already mentioned this scenario multiple times in this post: one of the key scenarios to handle in a Universal Windows app is the page’s lifecycle. Frequently, the navigation events are used to handle basic operations like data loading. As such, having access to these kind of events also in a ViewModel is critical, since usually all the logic is there. For this purpose, the **ViewModelBase** class offers a set of additional features to make the developer’s life easier. The first feature is the implementation of an interface called **INavigable**, which allows to access to the navigation events directly in a ViewModel, like in the following sample: <pre class="brush: csharp;">public class DetailViewModel : ViewModelBase { public override void OnNavigatedTo(object parameter, NavigationMode mode, IDictionary<string, object> state) { if (parameter != null) { int id = (int) parameter; //load data } } public override Task OnNavigatedFromAsync(IDictionary<string, object> state, bool suspending) { return base.OnNavigatedFromAsync(state, suspending); } }
</pre>
As you can see, thanks to this base class you get a 1:1 mapping with the same methods that are available in the code-behind class. You get also useful information about the navigation, like parameters that have been passed from another page or the **NavigationMode**, which can be useful to distinguish the different navigation scenarios (for example, you may decide to load the application’s data only when the **NavigationMode** parameter is set to **New**, which means that it’s a new navigation). Another navigation feature offered by the **ViewModelBase** class is the **NavigationService**, which is a helper that can be used to trigger the navigation from one page to another directly in the ViewModel. Again, this is a scenario that, without this helper, would be supported only in the code-behind class: navigation is handled, in fact, by the **Frame** class, which can be accessed only in code-behind. The **NavigationService** class is pretty straightforward to use, since it mimics the behavior of the **Frame** one: to navigate from one page to another you can use the **Navigate()** method, passing as information the page’s type and, optionally, a parameter. <pre class="brush: csharp;">NavigationService.Navigate(typeof(DetailPage), person?.Id);
</pre>
As you can see in the documentation, the **Navigate()** method accepts as parameter a generic **object**: however, it isn’t a good practice to pass complex objects from one page to another, but it’s better to stick with simple types (a string, a number, etc.). This way, we make sure not to break the state management system implemented by Template10 (that we’re going to see later), which requires that parameters needs to be serializable. ### ### Handle the page’s state One of the most important scenarios to handle in a Universal Windows app is the application’s lifecycle. When an application isn’t in foreground anymore, it’s suspended: the process is frozen in memory (so that the state is preserved) but all the threads that can use CPU, battery or network are terminated. When the application is resumed, we don’t have to do anything special: since the state was preserved in memory, the app will be restored exactly as it was. However, the operating system can decide to terminate a suspended application in case the resources are running low. In this case, since the process is completely killed, when the app is resumed it won’t automatically be restored to the previous state. As developers, we need to handle this scenario: since the termination by the OS is completely transparent to the user, he will expect to find the application as he left it. It’s our duty to properly save and restore the page’s state. Let’s say, for example, that our application includes a page with some fields that the user needs to fill before moving on (like a registration form). Once the application is suspended and then resumed, he would expect to find the data he already filled already there and not to fill the entire form from scratch. When you use the MVVM pattern, handling this scenario introduces some challenges: 1. Since we don’t know for sure if the suspended application will be terminated or not, we need to save the page’s state every time a new navigation is performed. When you use the MVVM pattern without relying on other libraries (like Template10), this requirement is hard to handle because we don’t have access to the navigation events in a ViewModel. 2. When the application is suspended, we need to save in the local storage the application’s state, like the content of the registration form or the last visited page. Then, when the application is resumed, we need to understand if it was terminated and, consequently, restore the state we’ve previously saved. Unfortunately, the basic Windows 10 template doesn’t offer any tool or API to make easier for the developer to support this scenario. Template10 makes the whole process a lot easier. When we have seen the sample code about handling the page’s lifecycle, you may have noticed that the **OnNavigatedTo()** and **OnNavigatedFrom()** events expose a parameter called **state**. It’s a dictionary, which can contain a list of key-value pairs, that are automatically serialized and deserialized in the local storage when the app is suspended or resumed. When the application is suspended, you’re going to use the **OnNavigatedFrom()** method to add in the dictionary all the information we need to recover the application’s state. When the page is loaded, instead, in the **OnNavigatedTo()** event, we’ll retrieve the previously saved info and we’ll assign them to the proper properties in the ViewModel. Let’s see a real sample, by defining a page with a **TextBox** control. The user can insert any text in it, which is saved into a ViewModel property, like the following one <pre class="brush: csharp;">private string _name;
public string Name {
get { return _name; } set { Set(ref _name, value); } }
</pre>
The property is connected, as usual, to the **TextBox** control using binding: <pre class="brush: xml;"><TextBlock Text="{Binding Path=Name, Mode=TwoWay}" />
</pre>
You can notice that the binding has been configured using the **TwoWay** mode: this way, every time the user will write something in the **TextBox**, the **Name** property in the ViewModel will be automatically updated with the new value. Now you can try to suspend the application and to open it back, by using the dropdown menu called **Lifecycle events** in Visual Studio, that allows to simulate the different stages of the application’s lifecycle. It’s important to remind, in fact, that when the debugger is attached, the app **is not suspended** when you put in background, like instead happens during the regular usage. If we write some text in the **TextBox** control, then we suspend the app and we open it back, we will find everything as we’ve left, since the app was just suspended and the process kept in memory. However, if we try to do the same but using the **Suspend and shutdown** option, you will notice that the content of the **TextBox** control will be gone: the process has been indeed terminated and, since we didn’t save the content of the **TextBox**, the data was lost during the restore process. [<img title="clip_image002" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="clip_image002" src="https://i1.wp.com/wp.qmatteoq.com/wp-content/uploads/2015/10/clip_image002_thumb.jpg?resize=240%2C109" width="240" height="109" data-recalc-dims="1" />](https://i1.wp.com/wp.qmatteoq.com/wp-content/uploads/2015/10/clip_image002.jpg) To avoid this issue we can use the dictionary I’ve previously mentioned: in the **OnNavigatedFrom()** method of the ViewModel we can understand if the app is being suspended and, eventually, save in the collection the information we need to restore the state. <pre class="brush: csharp;">public class DetailViewModel : ViewModelBase { private string _name; public string Name { get { return _name; } set { Set(ref _name, value); } } public override Task OnNavigatedFromAsync(IDictionary<string, object> state, bool suspending) { if (suspending) { state.Add("Name", Name); } return base.OnNavigatedFromAsync(state, suspending); } }
</pre>
By using the boolean parameter called **suspending** we understand if the app is being suspended: if that’s the case, we can save into the dictionary called **state** the value of the **Name** property, by matching it to a key with the same name. This way, during the suspension, Template10 will automatically take care of serializing the content of this dictionary into the local storage in a text file. Now it will be easier for you to understand one of the key requirements of this implementation: we can store into the dictionary only simple data, that can be serialized into XML or JSON file. Saving, for example, an image stream into the dictionary wouldn’t work. The next step is to handle the page loading: in case the **state** dictionary contains some data in the **OnNavigatedTo()** method, then it means that the app is being resumed from a suspension and we need to retrieve the. Also in this case most of the work will be done by Template10: the bootstrapper will take care of loading the data that was previously serialized and it will automatically redirect the user to the last visited page of the application. This way, we can simply access to the **state** parameter in the **OnNavigatedTo()** method and use the data to populate back the properties in our ViewModel, like in the following sample: <pre class="brush: csharp;">public class DetailViewModel : ViewModelBase { private string _name; public string Name { get { return _name; } set { Set(ref _name, value); } } public override void OnNavigatedTo(object parameter, NavigationMode mode, IDictionary<string, object> state) { if (state.Any()) { Name = state["Name"].ToString(); state.Clear(); } } public override Task OnNavigatedFromAsync(IDictionary<string, object> state, bool suspending) { if (suspending) { state.Add("Name", Name); } return base.OnNavigatedFromAsync(state, suspending); } }
</pre>
Inside the **OnNavigatedTo()** method we check if there is any data inside the dictionary: only in this case we retrieve the value identified by the **Name** key and we assign it to the proper ViewModel’s property. The next step is to clear the content of the collection (using the **Clear()** method), to avoid that the data is retrieved again also when we’re simply navigating from one page to another. Now we can try again to suspend the app using the **Suspend and shutdown** option offered by Visual Studio: now the application will behave as expected and the content of the **TextBox** control will still be there. **Important!** It’s crucial to remind that this approach has to be used to save the page’s state, not the application data. Data generated by the user has to be saved as soon as possible, to minimize data loss in case of unexpected errors. During the suspension, you have between 5 and 10 seconds to complete all the pending operations, which may not be enough to save all the data handled by your application. The only data we need to save during suspension are the one that makes easier for the developer to create the illusion that the app has never been closed, even if it was silently terminated by the operating system. ### ### ### Access to the UI thread Sometimes you may have the requirement, inside a ViewModel, to perform some operations on background threads. In this case, if we try to directly access to one of the UI controls (for example, because we need to change the value of a property which is connected to a control in the View), we ill get an exception: the reason is that we’re trying to access to the UI thread from a secondary one. The Windows Runtime offers a class called **Dispatcher** to solve this problem: it’s a sort of “mailman”, which is able to dispatch some operations to the UI thread, regardless of the thread where the execution is happening. Also in this case, we’re talking about a class which can be easily accessed from a code-behind class, but the same doesn’t apply to an independent class like a ViewModel. Template10 includes a helper that makes easier to access to the dispatcher also from a third party class, like a ViewModel, by exposing a property called **Dispatcher** as part of the **ViewModelBase** infrastructure: <pre class="brush: csharp;">await Dispatcher.DispatchAsync(() => { //do something on the UI thread });
</pre>
Using it is very easy: just call the **DispatchAsync()** method of the **Dispatcher** class by passing, as parameter, an **Action** with the operations that you want to perform on the UI thread. ### ### Wrapping up Template10 can be really helpful when you’re working with the MVVM pattern in a Universal Windows app: you can focus on getting things done, rather than trying to reinvent the wheel every time to handle the fundamentals of Universal Windows app development. However, Template10 is still growing and the number of services that will make easier to integrate Windows features into a ViewModel will continue to grow! For the moment, we’ve finished our journey to discover the Template10 features, but I’m sure we’ll have the chance to talk about it again in the future. Don’t forget that you can find all the information about the project, in addition to many samples, on the official GitHub repository <https://github.com/Windows-XAML/Template10>
in
- The model, which are the entities and the services that are used to handle the raw data of the application, without dependencies on how they are presented.
subscribe via RSS