Nico's digital footprint

I grew up in the nineties, that makes me awesome by default

A practical guide to MVVM (Light)

by Nico

You don’t have to look very far into the pits of the internet to find that there are still a lot of devs with questions on how to build a Windows / Windows Phone app with the MVVM pattern. In this article I’m going to explain my way of working. The libraries I use, how and why I use them. I hope this will clear some of the doubts others are having and helps you get on the right MVVM track.

What is MVVM?

Let’s start with walking through what MVVM is exactly. Feel free to skip this part if you already know because this has been discussed on almost every tech related website Glimlach

Let’s start with a diagram.


Source: c-sharpcorner.com

In MVVM there are three main parts, the Views, the Model and the ViewModels. The Model are just your basic POCO classes, nothing to fancy in there. The Views are your XAML files, the visual aspect of the application. The ViewModels are classes that get data from your data service classes and shape it into something the view is expecting.

Why these three parts? it’s a matter of seperation of concerns, the View doesn’t need to know where the data is coming from or in what format it’s delivered by the service. The only thing the View cares about is where it can get its data and it assumes that the data will be in the correct format. It gets that data from the ViewModel (or VM in short) through databinding. The View can make the VM do stuff by sending Commands its way, so View and ViewModel can interact with each other. The ViewModel reacts on those commands and requests data from the services, where that data comes from (in-memory, API, whatever, …) doesn’t matter for the VM, as long as it gets what it’s expecting.

Now, why would you use this? As mentioned before, it makes your code much cleaner by seperating the logic out of the View into the VM. It also makes the entire application much easier to unit test. You can just write tests against the ViewModels, since they are just normal .NET classes.

The endless discussion of code behind

There’s a small war among developers going on about MVVM. MVVM states that no code should exist in the code-behind of a view (for example MainPage.xaml.cs). Some people cling onto this statement, others take it as a “if you can”.

Here’s my opinion on the subject: MVVM is a design pattern, meaning that it’s a set of guidelines. Guidelines, as in “not set in stone”. Sometimes you need to jump through a lot of hoops to get something done in the VM while it’s much easier in the View. If you run into such a situation: decide if it’s worth spending time and research into the subject (and blog about it after you find the solution Knipogende emoticon). Another situation is things that have to do with the view. Things like changing a state in the Visual State Manager when switching from landscape to portrait, this is something that you can take to the ViewModel but in my opinion the VSM is pure View business, it has nothing to do with the ViewModel so that’s something I typically put into code behind.

As you can tell, the discussion isn’t really worth it. Just do whatever feels right for you (if you’re working in a team, make sure everyone is on the same page about this).

Let’s get started

Enough chit-chat, let’s get to the practical side of things. For this article I’m going to go with a Windows Phone 8.1 Silverlight project but a lot of the stuff here is applicable to any XAML technology, even ranging back to Windows Phone 7.

We’ll start with a blank slate, a brand new project started from the Blank App template. First thing you need to do when developing an MVVM application is add your MVVM stuff, either by adding a framework like Caliburn or by adding a toolkit with helper classes like MVVM Light (or by building your own of course). My weapon of choice in MVVM is always MVVM Light. Why? Because it’s a toolkit rather than a framework, it leaves a lot of the responsibilities in the hand of the developer. Frameworks like Caliburn rely more on conventions and that’s something I personally do not like. Other people have other preferences over this, so choice whatever feels right for you. For this article I’m using MVVM Light.

Let’s start by adding MVVM Light to the project. As with any good library, it’s on NuGet. If you search for MVVM Light on NuGet you’ll get some results, so what to pick? (I’ve marked the official MVVM Light NuGet packages in the screenshot).

Let’s go over them, top to bottom. The first one is the one I usually use. It adds the MVVM Light libraries to your project, creates a folder for the viewmodels, creates the MainViewModel and ViewModelLocator (more on this in a bit) and instantiates the ViewModelLocator in App.xaml. Quite a lot of work all done for you by the power of NuGet and PowerShell. The second NuGet package just adds the libraries to your project but it doesn’t create any folders or classes. The third package is the same as the second but as a Portable Class Library, use this one if you’re adding ViewModels in a PCL.

I usually go with the first one because of all the initial setup that occurs. Let’s add that package and have a look at the Solution Explorer.

For starters, NuGet added three libraries to the project. Why three? The first one is the actual MVVM Light library, the second one contains a bunch of extras like EventToCommand and SimpleIOC. In case you’re wondering why these are in a separate library, and where that Microsoft.Practices.ServiceLocation lib comes from, here’s Laurent’s answer to that:

“The Extras assembly exists because EventToCommand requires a reference to System.Windows.Interactivity, while ButtonBaseExtensions, RelayCommand, Messenger etc do not need it. Some people are reluctant to add references to assemblies if they can avoid it. So for those people who don't need EventtoCommand, they onlu use the base assembly, and the others who want the whole program can add Extras.

Cheers, Laurent”
Source: http://stackoverflow.com/questions/4740811/why-are-mvvmlight-command-and-mvvmlight-extras-wp7-both-needed

Let’s take a look at the generated code files, starting with MainViewModel (I removed some of the comments for brevity)

Code Snippet
  1. namespace MvvmDemo.ViewModel
  2. {
  3.     public class MainViewModel : ViewModelBase
  4.     {
  5.         public MainViewModel()
  6.         {
  7.             ////if (IsInDesignMode)
  8.             ////{
  9.             ////    // Code runs in Blend --> create design time data.
  10.             ////}
  11.             ////else
  12.             ////{
  13.             ////    // Code runs "for real"
  14.             ////}
  15.         }
  16.     }
  17. }

Not much in there, but there doesn’t need to be. That’s what I like about MVVM Light, it keeps things simple and, well Light Glimlach. ViewModels are defined by creating a class that inherits from ViewModelBase, the name of a ViewModel (or VM in short) doesn’t need to end in “ViewModel” but I tend to do this to make them recognizable. We’ll be discussing the piece of code that’s commented out in a bit.

Next up is the ViewModelLocator class (again, removed some comments for brevity).

Code Snippet
  1. public class ViewModelLocator
  2. {
  3.     /// <summary>
  4.     /// Initializes a new instance of the ViewModelLocator class.
  5.     /// </summary>
  6.     public ViewModelLocator()
  7.     {
  8.         ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
  9.  
  10.         ////if (ViewModelBase.IsInDesignModeStatic)
  11.         ////{
  12.         ////    // Create design time view services and models
  13.         ////    SimpleIoc.Default.Register<IDataService, DesignDataService>();
  14.         ////}
  15.         ////else
  16.         ////{
  17.         ////    // Create run time view services and models
  18.         ////    SimpleIoc.Default.Register<IDataService, DataService>();
  19.         ////}
  20.  
  21.         SimpleIoc.Default.Register<MainViewModel>();
  22.     }
  23.  
  24.     public MainViewModel Main
  25.     {
  26.         get
  27.         {
  28.             return ServiceLocator.Current.GetInstance<MainViewModel>();
  29.         }
  30.     }
  31.     
  32.     public static void Cleanup()
  33.     {
  34.         // TODO Clear the ViewModels
  35.     }
  36. }

So what is the ViewModelLocator? It’s the class that registers all the dataservices and viewmodels in the IOC container (if you don’t know what IOC is, read the next alinea, if you do know what it is you can skip the next part). The ViewModelLocator also provides properties for every ViewModel so we can easily bind a view to a viewmodel. The get part of these properties take the VM instance out of the IOC (again, read the next part for info on IOC) and returns it to the caller. Finally there’s a Cleanup method that you can use to cleanup viewmodels if you need to.

SideStep: IOC

Read this part if you’re not familiar with IOC, feel free to skip this part if you’ve already used IOC.
IOC, or Inversion Of Control, is often used in conjunction with DI or dependency injection. IOC is a technique used to make applications easily extensible and to increase the modularity. These goals can be achieved by using techniques like the Factory Pattern or Dependency Injection. With IOC and DI we can register classes in a so called container. Then, whenever we need one of those registered classes we can fetch the instance from the container instead of instantiating a new one, basically creating a Singleton effect. The big difference with a Singleton is that we can have dependency injection. If one of the classes contains a constructor that takes, for example, a dataservice as parameter and that dataservice is also registered in the container, the DI will inject the dataservice instance into the class with the constructor that takes in a dataservice. More over, we can use interfaces to register classes into the container. If that same class from before takes IDataService as a parameter, the registered instance of a class that implements IDataService will get injected into the constructor. This allows for a more abstract way of working.

Note: this was a basic explanation for IOC / DI. If you really want to get the hang of it, research it and use it, you’ll get it in no time. Some quick links to get you started (with thanks to Glenn Versweyveld for the links)

End of the sidestep: Marching on

MVVM Light has a built in IOC/DI framework called SimpleIoc. It’s exactly as the name implies, a very simple, basic framework but it gets the job done. In case that it wouldn’t fulfill your needs or you feel more comfortable with, for example, AutoFac, it’s really easy to swap SimpleIoc out and another framework in. See my “10 things you might have missed about MVVM Light” article from last year for a quick sample.

Okay, final part of the MVVM Light Powershell magic is something that happened inside the App.xaml. A resource was added to the Application.Resources

Code Snippet
  1. <Application.Resources>
  2.     <local:LocalizedStrings xmlns:local="clr-namespace:MvvmDemo" x:Key="LocalizedStrings" />
  3.     <vm:ViewModelLocator xmlns:vm="clr-namespace:MvvmDemo.ViewModel"
  4.                          x:Key="Locator"
  5.                          d:IsDataSource="True" />
  6. </Application.Resources>

The ViewModelLocator is added as an application resource, so it will get instantiated as soon as the application starts up. That means that all viewmodels and services are registered in the DI container right away. The resource is given a key so we can reference it when we set our datacontext in xaml.

Moving the View

MVVM Light puts the VM in the VM folder by default but the views are just hanging around in the project. If you don’t like this (as I do Glimlach) you can add a View folder and move the MainPage into that folder. Once it’s moved I have the habit of changing the namespace of MainPage to reflect the folder structure. This needs to happen in two places, xaml and code behind. In xaml find this line (it should be at the top)

Code Snippet
  1. x:Class="MvvmDemo.MainPage"

and change it to

Code Snippet
  1. x:Class="MvvmDemo.View.MainPage"

In code behind change the namespace to

Code Snippet
  1. namespace MvvmDemo.View

Right now, your application will compile perfectly but you will get a NavigationFailedException when launching. Open up the WMAppManifest.xml. On the Application UI tab is a textbox that says Navigation Page: MainPage.xaml. Navigating in Silverlight apps is still done using strings, so the compiler is happy here but at runtime the navigation target isn’t found at this location. Change it from MainPage.xaml to /View/MainPage.xaml and see if it works. If you entered the correct folder path the app should start.

Hooking up the View

Let’s get to the interesting part. We’re now ready to hook our view up on the viewmodel. This can be done from code behind or from XAML. I prefer the XAML way because it gives you some intellisense when binding to properties on the viewmodel, since the XAML designer knows of the datacontext if it’s defined in XAML.

This is what we need to add to the opening tag of a page to set the datacontext

Code Snippet
  1. DataContext="{Binding Main, Source={StaticResource Locator}}"

This is the full tag for reference:

Code Snippet
  1. <phone:PhoneApplicationPage x:Class="MvvmDemo.View.MainPage"
  2.                             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.                             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.                             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.                             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.                             xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  7.                             xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
  8.                             DataContext="{Binding Main,
  9.                                                   Source={StaticResource Locator}}"
  10.                             FontFamily="{StaticResource PhoneFontFamilyNormal}"
  11.                             FontSize="{StaticResource PhoneFontSizeNormal}"
  12.                             Foreground="{StaticResource PhoneForegroundBrush}"
  13.                             Orientation="Portrait"
  14.                             SupportedOrientations="Portrait"
  15.                             shell:SystemTray.IsVisible="True"
  16.                             mc:Ignorable="d">

If you don’t want to do it from XAML, it’s very easy to set it via Blend as well.

Open MainPage.xaml in Blend. Select PhoneApplicationPage in the Objects & Timeline pane.

In the properties pane, search for the DataContext Property and click on the white square next to it, select “Create databinding”

In the dialog that will popup, you’ll see the Locator key that we declared in App.xaml, Blend can interpret those resources and help you with binding to them. Select the Locator and you’ll see the Main property that is defined inside the ViewModelLocator (remember, the property that gets the MainViewModel instance from the container and returns it to the caller). Select that property and click OK, your binding is set!

Small thing about Blend: It’s AWESOME! period. If you don’t know how to use it, learn it. Learn to use it and you’ll automatically love it. Your apps will look much better and once you get the hang of using design time data you’ll get your design done much faster.

Adding our first binding

Let’s get some binding done! We’ll bind the title of the page to a property on the ViewModel just to get started. In the MainViewModel, Create a simple string autoproperty

Code Snippet
  1. public string Title { get; set; }

We’ll use the MainViewModel’s constructor to give this property some data. (line 3)

Code Snippet
  1. public MainViewModel()
  2. {
  3.     Title = "Hello World!";
  4.  
  5.     ////if (IsInDesignMode)
  6.     ////{
  7.     ////    // Code runs in Blend --> create design time data.
  8.     ////}
  9.     ////else
  10.     ////{
  11.     ////    // Code runs "for real"
  12.     ////}
  13. }

Now onto the view, find the TextBlock for the page title and add the binding statement to the Text attribute (this can be done from Blend, just like the datacontext property, select the textblock, find the text property and add data binding)

Code Snippet
  1. <TextBlock Margin="9,-7,0,0"
  2.            Style="{StaticResource PhoneTextTitle1Style}"
  3.            Text="{Binding Title}" />

The Text property now contains a Binding statement. This is always set between curly braces, followed by the word Binding and the name of the property we’re binding to. At runtime the CLR will try to find a property with that name in the datacontext of the TextBlock, since we’re not specifying a DataContext on the TextBlock it will take that of its parent control, that way we’ll finally reach the MainViewModel where the Title property is waiting for us. Run the app and behold the wonders of databinding in an MVVM scenario.

Now this works but if we were to change the Title property as it is right now, it wouldn’t reflect on the page. A bound property isn’t monitored or polled for changes, we need to trigger some sort of event to tell the subscribers that a property has changed and that they need to refresh their binding. Usually this is done by implementing INotifyPropertyChanged and calling the OnPropertyChanged event in the property’s setter. In the case of MVVM the INotifyPropertyChanged interface is already implemented in the ViewModelBase class, so all we have left to do is raise the event (or call a method that raises the event, that method is called RaisePropertyChanged and sits in the ViewModelBase) from the property’s setter.

Code Snippet
  1. private string _title;
  2.  
  3. public string Title
  4. {
  5.     get { return _title; }
  6.     set
  7.     {
  8.         if (_title == value) return;
  9.         _title = value;
  10.         RaisePropertyChanged(() => Title);
  11.     }
  12. }

We check if the property has really changed to avoid refreshing bindings when it’s not needed, if it does change we raise the event. According to the INotifyPropertyChanged interface we need to pass the property name as a string. MVVM Light’s ViewModelBase has an overload that takes a Func<string> so we can rely on intellisense to get the name of the property right. And with this we have a real databinding that will update the view when changed. Also, if you open MainPage in Blend now, you’ll notice that the binding is executed in design time as well. That’s one of Blend’s biggest strengths.

Using real fake data

Okay, so we now have databinding all set up, our MVVM structure is in place. Let’s build something that resembles an actual app. Create a Model folder in your project and add a Person class to it.

Code Snippet
  1. public class Person
  2. {
  3.     public string Picture { get; set; }
  4.     public int Age { get; set; }
  5.     public string Name { get; set; }
  6.     public string Company { get; set; }
  7.     public string Email { get; set; }
  8.     public string Phone { get; set; }
  9. }

Now to get some data I’ve used a website called json-generator to generate 15 instances of this class in Json format. You can download the JSON file I’ve used here

I placed the json in a static field in a static public class so my dataservice can easily get to it. I use this to simulate what could be a REST call in a real application. (if you want to know more about creating and calling REST services, read my article)

Add a folder called Services to the project and add an interface called IDataService.

Code Snippet
  1. public interface IDataService
  2. {
  3.     IEnumerable<Person> GetAll();
  4.     IEnumerable<Person> Get(Func<Person, bool> predicate);
  5.     Person GetByName(string name);
  6. }

The interface defines methods to fetch all the persons, to get a filtered set of persons by passing a predicate into a Where clause or fetch a specific person by name.

We’ll end up with two implementations of this interface. Let’s start with the first one, this one will be used at runtime and will query the actual service (the hardcoded JSON in this case, just assume it’s a call to a REST service). The first implementation is easy, the constructor fetches and deserializes the json. The methods then query that resultset.

Code Snippet
  1. public class DataService : IDataService
  2. {
  3.     private IEnumerable<Person> _persons;
  4.  
  5.     public DataService()
  6.     {
  7.         _persons = JsonConvert.DeserializeObject<IEnumerable<Person>>(Data.Data.Json);
  8.     }
  9.  
  10.     public IEnumerable<Person> GetAll()
  11.     {
  12.         return _persons;
  13.     }
  14.  
  15.     public IEnumerable<Person> Get(Func<Person, bool> predicate)
  16.     {
  17.         return _persons.Where(predicate);
  18.     }
  19.  
  20.     public Person GetByName(string name)
  21.     {
  22.         return _persons.FirstOrDefault(person => person.Name == name);
  23.     }
  24. }

Very basic data service, but enough to get my point across. Now it’s time to revisit the ViewModelLocator. When you look at the constructor of the ViewModelLocator you’ll notice that it contains a block of code that’s commented out.

Code Snippet
  1. public ViewModelLocator()
  2. {
  3.     ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
  4.  
  5.     ////if (ViewModelBase.IsInDesignModeStatic)
  6.     ////{
  7.     ////    // Create design time view services and models
  8.     ////    SimpleIoc.Default.Register<IDataService, DesignDataService>();
  9.     ////}
  10.     ////else
  11.     ////{
  12.     ////    // Create run time view services and models
  13.     ////    SimpleIoc.Default.Register<IDataService, DataService>();
  14.     ////}
  15.  
  16.     SimpleIoc.Default.Register<MainViewModel>();
  17. }

That piece of code is exactly what we need. Why? Because it checks if the code is being executed in runtime or in design time. As I’ve mentioned before, the Blend and Visual Studio designers execute the code whenever a page is loaded into the designer. We can use that to hook up dummy data. The ViewModelBase class from MVVM Light contains a static boolean that tells us if we’re in design mode. We can use this to either register DataService in the container or a design time version of DataService (which we’ll build in a minute).

Uncomment the code so it looks like this (don’t worry about the DesignDataService error, the class doesn’t exist yet but it’s the next step.

Code Snippet
  1. public ViewModelLocator()
  2. {
  3.     ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
  4.  
  5.     if (ViewModelBase.IsInDesignModeStatic)
  6.     {
  7.         // Create design time view services and models
  8.         SimpleIoc.Default.Register<IDataService, DesignDataService>();
  9.     }
  10.     else
  11.     {
  12.         // Create run time view services and models
  13.         SimpleIoc.Default.Register<IDataService, DataService>();
  14.     }
  15.  
  16.     SimpleIoc.Default.Register<MainViewModel>();
  17. }

In the Services folder, add a class called DesignDataService and make it implement IDataService.

Code Snippet
  1. public class DesignDataService : IDataService
  2. {
  3.     private List<Person> _persons;
  4.  
  5.     public DesignDataService()
  6.     {
  7.         _persons = new List<Person>();
  8.         Random rnd = new Random();
  9.  
  10.         for (int i = 0; i < 10; i++)
  11.         {
  12.             Person person = new Person
  13.             {
  14.                 Age = rnd.Next(10, 60),
  15.                 Company = "Design time company",
  16.                 Email = "design@time.com",
  17.                 Name = "Design time person " + i,
  18.                 Phone = "+1 (846) 597-3140",
  19.                 Picture = "http://files.softicons.com/download/tv-movie-icons/doctor-who-icons-by-rich-d/png/48/Tardis%203.png"
  20.             };
  21.  
  22.             _persons.Add(person);
  23.         }
  24.     }
  25.     public IEnumerable<Person> GetAll()
  26.     {
  27.         return _persons;
  28.     }
  29.  
  30.     public IEnumerable<Person> Get(Func<Person, bool> predicate)
  31.     {
  32.         return _persons.Where(predicate);
  33.     }
  34.  
  35.     public Person GetByName(string name)
  36.     {
  37.         return _persons.First();
  38.     }
  39. }

I use a for loop to create 10 design time persons. Note that the GetByName method just returns the first person in the list. For design time data it doesn’t matter if the correct data is returned, we’re only using this data to get the visual aspect of the application right. Verify that the app still compiles and let’s get this thing injected.

Open the MainViewModel. Add a field for the IDataService and add IDataService as a parameter for the constructor.

Code Snippet
  1. private readonly IDataService _dataService;
  2. public MainViewModel(IDataService dataService)
  3. {
  4.     _dataService = dataService;
  5.     Title = "Hello World!";
  6. }

This is where constructor injection will come into play. SimpleIoc will inject the registered implementation if IDataService right here in the constructor, if you want to see this set a breakpoint in the constructor, open the app and inspect the parameter.

Now I want a property that contains the persons and bind this to some sort of list element so we get a nice, scrollable overview of persons. The perfect collection for bindable properties is an ObservableCollection. It notifies subscribers whenever an item is added so that those newly added items are shown immediately. Add the property to the MainViewModel

Code Snippet
  1. private ObservableCollection<Person> _persons;
  2. public ObservableCollection<Person> Persons
  3. {
  4.     get { return _persons; }
  5.     set
  6.     {
  7.         if (_persons == value) return;
  8.         _persons = value;
  9.         RaisePropertyChanged(() => Persons);
  10.     }
  11. }

We’re going to use the constructor of the MainViewModel to get some data in.

Code Snippet
  1. public MainViewModel(IDataService dataService)
  2. {
  3.     _dataService = dataService;
  4.     Title = "Hello World!";
  5.  
  6.     IEnumerable<Person> persons = _dataService.GetAll();
  7.     Persons = new ObservableCollection<Person>(persons);
  8. }

The constructor of ObservableCollection<T> has an overload that takes in an IEnumerable<T> that can be used to seed the collection.

Blending it in

Let’s dive into Blend and get that design time data to work. Open MainPage.xaml in Blend. In the Data tab in Blend you’ll notice that MainViewModel shows up as Data Context, if you expand the tree structure you’ll find your ObservableCollection (if you don’t see it, switch back to Visual Studio and Build the solution, Blend doesn’t always update unless you build the project). Take the Persons property there and drag/drop it onto the design view (make sure MainPage.xaml is opened in design). When dragging over the design you should see this message appear.

Release the mouse button and a ListBox will be created and its ItemsSource wil lbe bound to that list on our MainViewModel. But it doesn’t look quite right.

This is common in Blend and is easily fixed, right-click the ListBox, go to Layout and select “Reset all”

Note: this is currently a ListBox, we are advised by Microsoft to use LongListSelector instead of ListBox for performance reasons. To change this, go into the xaml and change <ListBox… to <phone:LongListSelector.. Blend will keep working just like it’s doing now. For this article I’m just going to stick to ListBox but the way of working is the same.

We have a list of design time items now. Let’s run the app and see how it looks.

Notice how the data is different? The ViewModelLocator has registered the real DataService into the container so we’re now getting our real data instead of the design time data.

This doesn’t look very well, let’s see what we can do to change that. Blend makes changing item templates really easy, right-click the Listbox > “Edit Additional Templates” > “Edit Generated items (ItemTemplate)” > “Edit Current”

Have a look at the Objects & Timeline pane, you’ll see that it’s changed and shows the itemTemplate

From here you can create your entire layout, drag and drop properties from the Data tab onto the elements to create databindings. After about a minute I came up with this result.

The XAML for the itemtemplate:

Code Snippet
  1. <DataTemplate x:Key="PersonTemplate">
  2.     <Grid Margin="0,0,0,12">
  3.         <Grid.ColumnDefinitions>
  4.             <ColumnDefinition Width="Auto" />
  5.             <ColumnDefinition />
  6.         </Grid.ColumnDefinitions>
  7.         <Border Width="100"
  8.             Height="100"
  9.             HorizontalAlignment="Left"
  10.             VerticalAlignment="Top"
  11.             BorderBrush="Black"
  12.             BorderThickness="1">
  13.             <Image Source="{Binding Picture}" />
  14.         </Border>
  15.         <StackPanel Grid.Column="1">
  16.             <TextBlock Style="{StaticResource PhoneTextLargeStyle}" Text="{Binding Name}" />
  17.             <TextBlock Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Company}" />
  18.         </StackPanel>
  19.     </Grid>
  20. </DataTemplate>

Result in runtime:

Splitting this post + Conclusion

I’m going to split this up in two posts as this one’s long enough already and my keyboard is getting tired Glimlach

Part two will focus on selecting a person from the list, navigating to a detail page, fetching and showing the details. Expect it to show up some time next week (I’ll update this post as well as soon is its ready).

In this first part I’ve discussed what MVVM was and why you should do it. I’ve shown you how I use MVVM Light and walked through the setup. We’ve also discussed design-time data and how Blend combined with this designtime data can help you getting a nice UI in a fast way.

The code for this first part can be found on my OneDrive.


Tags:

.Net | Data | MVVM Light | Patterns | WP7 | WP8 | WinRT | XAML

Branching XAML Styler

by Nico

Some time ago I blogged about having recompiled the great XAML Styler plugin so it would install into Visual Studio 2013. The recompiled plugin suddenly became an unexpected success and it got me thinking that this plugin should really continue to exist, even if the original author isn’t supporting it anymore (not sure of this but it has been quite some time since he pushed anything to Codeplex).

After waiting around a bit I’ve decided to download the original source code, get it up and running in Visual Studio 2013 and push it to both Github and the Visual Studio gallery. So I’m happy to announce that the code can be found at Github and the VS2013 version of the plugin can be found at the Visual Studio Gallery

The future?

The version that is now on the gallery is the exact same version that I’ve compiled back in November. It’s the plugin that the original author created but recompiled with the VS2013 SDK. I did create a new VS Package project to be able to have it on the gallery side by side with the original plugin.

As for the future of the project, I’m currently going through the source code, getting to know the application and the code that makes it tick. Afterwards I’m planning on having a look at the logged issues on the original Codeplex site and tackle those.

Issues

Should you run into any issues while using the forked plugin please log an issue on the Github page.

Contributions

So you want to contribute? Great! Fork the Github version and go wild! Create a Pull request when you’re ready and if everything checks out I’ll happily merge your changes into the main branch and give props to every contribution you make.

Let’s keep this plugin alive and make it even better together!


Tags:

.Net | Community | Patterns | Silverlight | WP7 | WP8 | WPF | WinRT | Windows 8 | XAML | github | OSS

Porting a real win8 app to WP8–part 3

by Nico

It’s been a good while since I last worked on porting Comic Cloud from Windows 8 to Windows Phone. If you can still remember, the goal was to maximize code reuse by using PCL wherever possible.

Part 3 will be the last part in this series, I’m currently holding a fully functional Windows Store app and a Windows Phone 8 app that can navigate pages and sent a search query to the api using a shared service layer. Theoretically everything is shared between the two platforms except the views, which makes sense. But it still required quite a lot of tinkering to get it to work.

PCL is improving

Microsoft is working hard on bringing as many libraries to PCL as they possibly can. In part 2 of the series I already mentioned the portable HttpClient, that library finally gave us a uniform way of doing HTTP requests on multiple platforms. Between part 2 and this part Microsoft has released the PCL version of their Azure Mobile Services SDK (beware! this one has breaking changes if you’re coming over from the platform specific SDK).

Changes in my project

I decided not to use the PCL version of WAMS yet because it has breaking changes and it doesn’t help me get rid of some platform specific projects, so no real use there yet.

What I wanted to achieve for demoing purpose was to get the search functionality working on the phone. The search function on the Windows Store app uses a BlockingCollection (MSDN link) This is a thread safe collection, meaning I can safely prefetch data from one thread while loading data on the other thread. My entire search service is relying on this class (it’s an implementation of the consumer/producer pattern by the way), only problem: Windows Phone doesn’t have the BlockingCollection class. So I could either abstract the search service, change it entirely or implement my own version of the BlockingCollection. The last option seemed like the hardest one to do so I went for it. I’m not entirely sure if I got the exact same functionality of the real BlockingCollection (it does lack some methods and properties, I only implemented what I needed for my app) but here it is

Code Snippet
  1. public class BlockingCollection<T> : Queue<T>
  2. {
  3.     private readonly object _locker = new object();
  4.     private readonly Queue<T> _itemQ;
  5.     private bool _canAddItems;
  6.  
  7.     public BlockingCollection()
  8.     {
  9.         _itemQ = new Queue<T>();
  10.         _canAddItems = true;
  11.     }
  12.  
  13.     public void EnqueueItem(T item)
  14.     {
  15.         lock (_locker)
  16.         {
  17.             _itemQ.Enqueue(item); // We must pulse because we're
  18.             Monitor.Pulse(_locker); // changing a blocking condition.
  19.         }
  20.     }
  21.  
  22.     public bool TryTake(out T item, int millisecondsTimeout, CancellationToken cancellationToken)
  23.     {
  24.         cancellationToken.ThrowIfCancellationRequested();
  25.  
  26.         if (_canAddItems)
  27.         {
  28.             lock (this)
  29.             {
  30.                 try
  31.                 {
  32.                     item = Dequeue();
  33.                     return true;
  34.                 }
  35.                 catch (Exception)
  36.                 {
  37.                     item = default(T);
  38.                     return false;
  39.                 }
  40.             }
  41.         }
  42.  
  43.         item = default(T);
  44.         return false;
  45.     }
  46.  
  47.     public bool TryAdd(T item, int millisecondsTimeout, CancellationToken cancellationToken)
  48.     {
  49.         cancellationToken.ThrowIfCancellationRequested();
  50.  
  51.         if (_canAddItems)
  52.         {
  53.             lock (this)
  54.             {
  55.                 try
  56.                 {
  57.                     Enqueue(item);
  58.                     return true;
  59.                 }
  60.                 catch (Exception)
  61.                 {
  62.                     return false;
  63.                 }
  64.             }
  65.         }
  66.  
  67.         return false;
  68.     }
  69.  
  70.     public void CompleteAdding()
  71.     {
  72.         _canAddItems = false;
  73.     }
  74. }

It’s basically a Queue with some lock statements, it does work for me but I’m not responsible for any accidents that might occur Glimlach

Sharing ViewModels

All my viewmodels are in a PCL library, managed to get that to work in part 1. The ViewModelLocator can’t be made portable since some using statements are different and the WP8 version might need some other classes then the win8 version. I decided to add the Windows Store ViewModelLocator as a link into the Windows Phone 8 project, adding in some pre-processor directives made it work like a charm (I make this sound easy but it did take some time to get it just right).

Code Snippet
  1. using ComicDB.Framework;
  2. using ComicDB.SDKBroker;
  3. using ComicDB.View;
  4. using GalaSoft.MvvmLight;
  5. using GalaSoft.MvvmLight.Ioc;
  6. using Microsoft.Practices.ServiceLocation;
  7.  
  8. #if !WINDOWS_PHONE
  9. using ComicDB.Framework.WinRT;
  10. using ComicDB.SDKBroker.WinRT;
  11. #else
  12. using ComicDB.Framework.WP8;
  13. using ComicDB.SDKBroker.WP8;
  14. #endif
  15.  
  16. namespace ComicDB.ViewModel
  17. {
  18.     public class ViewModelLocator
  19.     {
  20.         public ViewModelLocator()
  21.         {
  22.             ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
  23.  
  24.             if (ViewModelBase.IsInDesignModeStatic)
  25.             {
  26.                 // Create design time view services and models
  27.                 //SimpleIoc.Default.Register<IDataService, DesignDataService>();
  28.             }
  29.             else
  30.             {
  31.                 // Create run time view services and models
  32. #if !WINDOWS_PHONE
  33.                 SimpleIoc.Default.Register<ComicDB.Framework.Interface.INavigationService, ComicDB.Framework.WinRT.NavigationService>();
  34. #else
  35.                 SimpleIoc.Default.Register<ComicDB.Framework.Interface.INavigationService, ComicDB.Framework.WP8.NavigationService>();
  36. #endif
  37.                 SimpleIoc.Default.Register<IService, Service>();
  38.                 SimpleIoc.Default.Register<IMessageApi, MessageApi>();
  39.                 SimpleIoc.Default.Register<IFrameworkApi, FrameworkApi>();
  40.                 SimpleIoc.Default.Register<IDispatcher, Dispatcher>();
  41.                 SimpleIoc.Default.Register<INetworkApi, NetworkApi>();
  42.             }
  43.  
  44.             //register views
  45. #if !WINDOWS_PHONE
  46.             SimpleIoc.Default.Register<IMainPage, MainPage>();
  47.             SimpleIoc.Default.Register<IVolumeDetailPage, VolumeDetailPage>();
  48.             SimpleIoc.Default.Register<ICharacterDetailPage, CharacterDetailPage>();
  49.             SimpleIoc.Default.Register<ICollectionPage, CollectionPage>();
  50.             SimpleIoc.Default.Register<IDetailPage, DetailPage>();
  51.             SimpleIoc.Default.Register<IIssueDetailPage, IssueDetailPage>();
  52.             SimpleIoc.Default.Register<ILocationDetailPage, LocationDetailPage>();
  53.             SimpleIoc.Default.Register<INewsFeedPage, NewsFeedPage>();
  54.             SimpleIoc.Default.Register<IPersonDetailPage, PersonDetailPage>();
  55.             SimpleIoc.Default.Register<IStoryArcDetailPage, StoryArcDetailPage>();
  56.             SimpleIoc.Default.Register<ITeamDetailPage, TeamDetailPage>();
  57. #endif
  58.             //register viewmodels
  59.             SimpleIoc.Default.Register<MainViewModel>();
  60.             SimpleIoc.Default.Register<VolumeDetailViewModel>(true);
  61.             SimpleIoc.Default.Register<CharacterDetailViewModel>(true);
  62.             SimpleIoc.Default.Register<TeamDetailViewModel>(true);
  63.             SimpleIoc.Default.Register<IssueDetailViewModel>(true);
  64.             SimpleIoc.Default.Register<SearchViewModel>();
  65.             SimpleIoc.Default.Register<DetailViewModel>(true);
  66.             SimpleIoc.Default.Register<StoryArcDetailViewModel>(true);
  67.             SimpleIoc.Default.Register<LocationDetailViewModel>(true);
  68.             SimpleIoc.Default.Register<PersonDetailViewModel>(true);
  69.             SimpleIoc.Default.Register<CollectionViewModel>();
  70.             SimpleIoc.Default.Register<NewsFeedViewModel>(true);
  71.         }
  72.  
  73.         public MainViewModel Main
  74.         {
  75.             get
  76.             {
  77.                 return ServiceLocator.Current.GetInstance<MainViewModel>();
  78.             }
  79.         }
  80.         //... all other VM properties follow here, left out for demo purpose

The pre-processor directives make the class look a bit dirty but it does get the job done.

At this point the WP8 app started and showed me the mainpage, with the mainviewmodel being its datacontext. Now I wanted to add an appbar with a searchbutton, a few problems there:

  • the default appbar is not bindable (solved with Cimbalino)
  • the mainviewmodel doesn’t have a command to navigate to the searchpage since Windows Store uses the Search charm

I decided to take the quick and dirty solution here so I added a normal appbar with a button and a navigation statement in code behind. The SearchPage has SearchViewModel as datacontext. In Windows Store it was normal for the SearchText property to be immediately holding a value since it came from the Search charm, not the case in WP8. Small change to the viewmodel so that it doesn’t fire its Search function when SearchText is empty or null. This was the result after all my hard work

 

Mission accomplished!

Conclusion

PCL still has a long way to go but it is improving, and for some cases it can actually already be very useful (for example to share model classes over different platforms).

I would however advice against going for maximum code reuse, it all sounds great but the reality is very different. I had to make a lot of decisions, change quite a lot of architecture and even add missing classes (like the BlockingCollection).

My advice if you want to build a multiplatform app: use PCL to share your model, maybe even some small framework with helper classes, but build a custom implementation of service layers and viewmodels for each platform, it will save you a lot of hassle and probably even time. If you do decide to go for maximum code reuse, make sure that you really really think about it when you design your architecture, make sure that every little thing has an abstraction better one interface too many than having to rewrite a class.

Here’s a comparing screenshot between the solution before and after adding the WP8 project and refactoring everything.


Tags:

.Net | Devices | Metro | PCL | Patterns | WP8 | WinRT | Windows 8 | XAML

SQLite with a bit of MVVM Light in Windows Phone 8

by Nico

While SQLce is still a viable solution in Windows Phone 8 to have some form of local database we also have an official SQLite implementation available. So why use SQLite when we can just keep using SQLce? Because Windows 8 only support SQLite and if you ever want to port over your app it would be nice not to have two versions of local databases to maintain. In this post I’ll explain how to implement a SQLite database into an MVVM Light Windows Phone 8 project (there is an unofficial Windows Phone 7 SQLite version as well but I have no idea how stable / buggy that is). I’ll be using Tim Heuer’s SQLite .net wrapper so we can use LINQ to SQLite instead of writing SQL queries manually (hooray for intellisense Smile). Let’s kick things off by creating an empty Windows Phone 8 app.

SQLite

Before we can use SQLite, we’ll need to install the SDK. Click here (official SQLite download page) to download the VSIX file and install it into Visual Studio.

NuGet fun

Before we can write any code we’ll need some NuGet packages. Use these commands in the Package Manager Console.

Install-Package MvvmLight

Install-Package sqlite-net

Install-Package WPtoolkit

Install-Package Cimbalino.Phone.Toolkit

Changing target platform

SQLite is a C++ library, meaning that it should be compiled against the architecture that the app will be running on. On Windows 8 that means creating separate packages for ARM and x86. On Windows Phone 8 that means switching from Any CPU to ARM when running on a device or when creating your XAP. When you’re running your app on the emulator the target platform needs to be set to x86.

Moving files around

When you  install the MVVM Light package it will add some folder structure and some files. I like to adjust this a bit more by adding a View folder and moving the MainPage into that view. That means that the startup page has to change as well. Open up the WMAppManifest.xml and change it like on the screenshot.

At this stage I couldn’t build the project because of a whole bunch of compile errors in the sqlite-net files. If you get the same problem (by the time you read this, it might be fixed), download the sqlite-net source from GitHub and from your project, add a reference to your local sqlite-net repo/lib/wp7/Community.CsharpSqlite.WinPhone.dll and that should fix it right up. Also, add a folder “Model” to the project so that our MVVM folder structure is complete.

The demo app

The app that we’ll be creating today is an app to keep track of tasks, which seems to be the new “Hello, World!”. We’ll start with the model, and work our way up to the view from there. Our class is called “Task” that means we’ll have to be careful that we use Model.Task instead of System.Threading.Task but we’ll manage.

Code Snippet
  1. [Table("Tasks")]
  2. public class Task : INotifyPropertyChanged
  3. {
  4.     private int _id;
  5.     private string _title;
  6.     private DateTime _date;
  7.  
  8.     [PrimaryKey, AutoIncrement]
  9.     public int Id
  10.     {
  11.         get { return _id; }
  12.         set
  13.         {
  14.             if (value == _id) return;
  15.             _id = value;
  16.             OnPropertyChanged("Id");
  17.         }
  18.     }
  19.  
  20.     public string Title
  21.     {
  22.         get { return _title; }
  23.         set
  24.         {
  25.             if (value == _title) return;
  26.             _title = value;
  27.             OnPropertyChanged("Title");
  28.         }
  29.     }
  30.  
  31.     public DateTime Date
  32.     {
  33.         get { return _date; }
  34.         set
  35.         {
  36.             if (value.Equals(_date)) return;
  37.             _date = value;
  38.             OnPropertyChanged("Date");
  39.         }
  40.     }
  41.  
  42.     public event PropertyChangedEventHandler PropertyChanged;
  43.     protected virtual void OnPropertyChanged(string propertyName = null)
  44.     {
  45.         PropertyChangedEventHandler handler = PropertyChanged;
  46.         if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
  47.     }
  48. }

The “Task” class implements INotifyPropertyChanged so that controls that are bound to its properties get updated like good citizens. Now for the annotations, those come from sqlite-net and mark this class as a table in the database. The same goes for the annotations on the Id property, that property is marked as being the primarykey and being an autoincremented value. If you have a property that you don’t want in the database, add the [Ignore] attribute and there won’t be any column generated for it. Now that we have a model we can start working on the service, the class that will do all the SQLite communication. (Yes we could do all this in the viewmodel but it’s called seperation of concerns Smile). And to do this the right way we’ll start by creating an interface for the service.

Code Snippet
  1. public interface IDataService
  2. {
  3.     Task SaveTask(Model.Task newTask);
  4.     Task<IList<Model.Task>> LoadTasks();
  5.     Task UpdateTask(Model.Task selectedTask);
  6.     Task DeleteTask(Model.Task selectedTask);
  7. }

Those are all the basic CRUD (Create, Read, Update, Delete) that we can (should be able to) perform on any datacontainer. Here’s the implementation

Code Snippet
  1. public class DataService : IDataService
  2. {
  3.     public async Task SaveTask(Model.Task newTask)
  4.     {
  5.         await App.Connection.InsertAsync(newTask);
  6.     }
  7.  
  8.     public async Task<IList<Model.Task>> LoadTasks()
  9.     {
  10.         return await App.Connection.Table<Model.Task>().ToListAsync();
  11.     }
  12.  
  13.     public async Task UpdateTask(Model.Task selectedTask)
  14.     {
  15.         await App.Connection.UpdateAsync(selectedTask);
  16.     }
  17.  
  18.     public async Task DeleteTask(Model.Task selectedTask)
  19.     {
  20.         await App.Connection.DeleteAsync(selectedTask);
  21.     }
  22.  
  23.     public async Task<IList<SubTask>> LoadSubTasks()
  24.     {
  25.         return await App.Connection.Table<SubTask>().ToListAsync();
  26.     }
  27. }

Hmm looks like I forgot to mention something, go to App.xaml.cs and add this property

Code Snippet
  1. public static SQLiteAsyncConnection Connection { get; set; }

Keep App.xaml.cs open, we’ll need it in a minute. In the DataService class we’re calling all the CRUD methods provided to us by sqlite-net. We can get a list of all records in a table by calling .Table<T>().ToListAsync() or do any of the other CRUD operations by just calling the function and passing in the modified POCO. Really easy and quite powerful.

Let’s jump back to App.xaml.cs, there should be an empty function called Application_Launching. In this function we’ll need to check if the database exists, open a connection to it if it exists or create it first and then open the connection.

Code Snippet
  1. private async void Application_Launching(object sender, LaunchingEventArgs e)
  2. {
  3.     try
  4.     {
  5.         await ApplicationData.Current.LocalFolder.GetFileAsync("taskDB.db");
  6.         Connection = new SQLiteAsyncConnection("taskDB.db");
  7.     }
  8.     catch (FileNotFoundException)
  9.     {
  10.         CreateDB();
  11.     }
  12. }

Unfortunately, there is no DataBaseExists() function like in SQLce so I choose to do it the quick and dirty way. I try to get the database, which is basically a file in the ApplicationData, if the file doesn’t exist it will throw a FileNotFoundException and that’s where I call the CreateDB() method.

Code Snippet
  1. private async void CreateDB()
  2. {
  3.     Connection = new SQLiteAsyncConnection("taskDB.db");
  4.  
  5.     await Connection.CreateTableAsync<Task>();
  6. }

Line 3 creates the database while line 5 creates the Task table in the database. When all that’s in place, we’re ready to move to the viewmodels.

ViewModel

Not much to say here, we all know what a viewmodel is, so here is the MainViewModel.

Code Snippet
  1. public class MainViewModel : ViewModelBase
  2. {
  3.     private readonly IDataService _dataService;
  4.     private readonly INavigationService _navigationService;
  5.  
  6.     /// <summary>
  7.     /// The <see cref="Tasks" /> property's name.
  8.     /// </summary>
  9.     public const string TasksPropertyName = "Tasks";
  10.  
  11.     private IList<Task> _tasks;
  12.  
  13.     /// <summary>
  14.     /// Sets and gets the Tasks property.
  15.     /// Changes to that property's value raise the PropertyChanged event.
  16.     /// </summary>
  17.     public IList<Task> Tasks
  18.     {
  19.         get
  20.         {
  21.             return _tasks;
  22.         }
  23.  
  24.         set
  25.         {
  26.             if (Equals(_tasks, value))
  27.             {
  28.                 return;
  29.             }
  30.  
  31.             RaisePropertyChanging(TasksPropertyName);
  32.             _tasks = value;
  33.             RaisePropertyChanged(TasksPropertyName);
  34.         }
  35.     }
  36.        
  37.     /// <summary>
  38.     /// The <see cref="NewTask" /> property's name.
  39.     /// </summary>
  40.     public const string NewTaskPropertyName = "NewTask";
  41.  
  42.     private Task _newTask;
  43.  
  44.     /// <summary>
  45.     /// Sets and gets the NewTask property.
  46.     /// Changes to that property's value raise the PropertyChanged event.
  47.     /// </summary>
  48.     public Task NewTask
  49.     {
  50.         get
  51.         {
  52.             return _newTask;
  53.         }
  54.  
  55.         set
  56.         {
  57.             if (_newTask == value)
  58.             {
  59.                 return;
  60.             }
  61.  
  62.             RaisePropertyChanging(NewTaskPropertyName);
  63.             _newTask = value;
  64.             RaisePropertyChanged(NewTaskPropertyName);
  65.         }
  66.     }
  67.  
  68.     public RelayCommand SaveNewTaskCommand
  69.     {
  70.         get { return new RelayCommand(SaveNewTask); }
  71.     }
  72.  
  73.     public RelayCommand<SelectionChangedEventArgs> SelectionChangedCommand
  74.     {
  75.         get { return new RelayCommand<SelectionChangedEventArgs>(SelectionChanged);}
  76.     }
  77.  
  78.     /// <summary>
  79.     /// Initializes a new instance of the MainViewModel class.
  80.     /// </summary>
  81.     public MainViewModel(IDataService dataService, INavigationService navigationService)
  82.     {
  83.         _dataService = dataService;
  84.         _navigationService = navigationService;
  85.         NewTask = new Task { Date = DateTime.Today };
  86.  
  87.         LoadTasks();
  88.     }
  89.  
  90.     private async void LoadTasks()
  91.     {
  92.         Tasks = await _dataService.LoadTasks();
  93.     }
  94.  
  95.     private async void SaveNewTask()
  96.     {
  97.         await _dataService.SaveTask(NewTask);
  98.         Tasks.Add(NewTask);
  99.         NewTask = new Task { Date = DateTime.Today };
  100.     }
  101.  
  102.     private void SelectionChanged(SelectionChangedEventArgs args)
  103.     {
  104.         if (args.AddedItems.Count > 0)
  105.         {
  106.             Messenger.Default.Send(new TaskSelectedMessage(args.AddedItems[0] as Task));
  107.             _navigationService.NavigateTo(new Uri(@"/View/EditPage.xaml", UriKind.Relative));
  108.         }
  109.     }
  110. }

The IDataService field is what we’ve defined just a minute ago, it gets instantiated through the constructor. INavigationService comes from the Cimbalino toolkit, it allows us to do page to page navigation from within the viewmodels. There’s a property of IList<Task> that one will hold all the available tasks, they are loaded at startup, also newly added tasks will be put in that list. There’s a property of type Task, his properties will be bound to the input fields on the new task form, when the user clicks save the property will be pushed to the dataservice to save it in the database. Talking about the save button, there are two RelayCommands (MVVM Light’s implementation of ICommand). One is for saving a new property and the second one is for navigating to the detail page when a task is selected. In the constructor both fields are set and the Task property is initialized, setting the date to today. Since our datepicker will be bound to this property it will automatically be set to today’s date. Loading all the tasks needs to be done asynchronous, since the constructor can’t be marked as async we’ll put the service call in a synchronous method and call that one from the constructor, that way we can use the async / await keywords. Saving a task is as easy as calling the SaveTask function on IDataService and adding the new task to the list, and reinitializing it afterwards to clear all the fields. You might want to think about adding some check here in case something goes wrong while saving to the DB (have it return a boolean for example), I’ll just be living on the edge here and assume this never fails Smile. For navigating to the detail page we’ll add a command to the SelectionChanged event of our LongListSelector. We use the MVVM Light messenger, some sort of implementation of the Observer pattern, to send over the selected item to anyone registered to listen to a message of type TaskSelectedMessage. The TaskSelectedMessage class is pretty basic.

Code Snippet
  1. public class TaskSelectedMessage : MessageBase
  2. {
  3.     public Model.Task Task { get; set; }
  4.  
  5.     public TaskSelectedMessage(Model.Task task)
  6.     {
  7.         Task = task;
  8.     }
  9. }

The class inherits from MessageBase, which is a class in the MVVM Light library, it has one property that is set in the constructor (that’s just to make life a bit easier).

In the MainViewModel, when the SelectionChanged event fires we send a message of this type containing the selected item, once the message is on its way we use the INavigationService to navigate to the detail page.

Here’s the  viewmodel for the editpage.

Code Snippet
  1. public class EditViewModel : ViewModelBase
  2. {
  3.     private readonly IDataService _dataService;
  4.     private readonly INavigationService _navigationService;
  5.  
  6.     /// <summary>
  7.     /// The <see cref="SelectedTask" /> property's name.
  8.     /// </summary>
  9.     public const string SelectedTaskPropertyName = "SelectedTask";
  10.  
  11.     private Task _selectedTask;
  12.  
  13.     /// <summary>
  14.     /// Sets and gets the SelectedTask property.
  15.     /// Changes to that property's value raise the PropertyChanged event.
  16.     /// </summary>
  17.     public Task SelectedTask
  18.     {
  19.         get
  20.         {
  21.             return _selectedTask;
  22.         }
  23.  
  24.         set
  25.         {
  26.             if (_selectedTask == value)
  27.             {
  28.                 return;
  29.             }
  30.  
  31.             RaisePropertyChanging(SelectedTaskPropertyName);
  32.             _selectedTask = value;
  33.             RaisePropertyChanged(SelectedTaskPropertyName);
  34.         }
  35.     }
  36.  
  37.     public RelayCommand UpdateTaskCommand
  38.     {
  39.         get { return new RelayCommand(UpdateTask); }
  40.     }
  41.  
  42.     public RelayCommand DeleteTaskCommand
  43.     {
  44.         get { return new RelayCommand(DeleteTask); }
  45.     }
  46.  
  47.     public EditViewModel(IDataService dataService, INavigationService navigationService)
  48.     {
  49.         _dataService = dataService;
  50.         _navigationService = navigationService;
  51.  
  52.         Messenger.Default.Register<TaskSelectedMessage>(this, msg => SelectedTask = msg.Task);
  53.     }
  54.  
  55.     private void UpdateTask()
  56.     {
  57.         _dataService.UpdateTask(SelectedTask);
  58.     }
  59.  
  60.     private void DeleteTask()
  61.     {
  62.         _dataService.DeleteTask(SelectedTask);
  63.     }
  64. }

The same fields can be found here (I could put them in a base class, would be cleaner but who cares about clean code anyway? – well you should all care!). One property in this viewmodel, to hold the selected task and bind its properties to the view. A few commands for update and delete, they just call their respective functions on the DataService passing in the selected Task. The interesting part here is in the constructor. The fields get set and we register the viewmodel to listen if the messenger has a message of type TaskSelectedMessage, if it does set the task in the message to the property. However, the viewmodel by default gets instantiated when we navigate to the view meaning that the message has left the building before the receiver has registered as a receiver so it won’t arrive. Let’s fix that shall we? When you’ve added the MVVM Light libraries through NuGet (or you used the MVVM Light project templates) there should be a ViewModelLocator class in your ViewModel folder. This class registers your viewmodels in the TinyIoc container. Registering those viewmodels has an overload that, when set to True, creates an instance of each viewmodel at application launch, meaning that the viewmodels register themselves on the messenger before any message can be send. Here are my viewmodel registrations (from the ViewModelLocator constructor).

Code Snippet
  1. SimpleIoc.Default.Register<MainViewModel>();
  2. SimpleIoc.Default.Register<EditViewModel>(true);

MainViewModel won’t get instantiated at registration but EditViewModel will. So that’s a problem solved. Next piece of the puzzle are those constructor parameters in the viewmodels. They get resolved by dependency injection, we register the correct types here in the ViewModelLocator and when the viewmodel constructor is called, the correct instances will get injected automagically.

Code Snippet
  1. if (ViewModelBase.IsInDesignModeStatic)
  2. {
  3.     // Create design time view services and models
  4.     SimpleIoc.Default.Register<IDataService, DesignService>();
  5. }
  6. else
  7. {
  8.     // Create run time view services and models
  9.     SimpleIoc.Default.Register<IDataService, DataService>();
  10.     SimpleIoc.Default.Register<INavigationService, NavigationService>();
  11. }

Take this for example, when we are in design mode (Blend for example) we can load an IDataService implementation that returns dummy data so that we can style our views very easily (code gets executed when running at designtime so even when you’re not using dummy data it’s a good idea to register these types in an if-block to prevent design time errors).

What everything in place, let’s have a look at the xaml and hook everything up. We’ll start with the MainPage.xaml and since XAML has a tendency of growing quite large, I’ll chop it in pieces. First thing a page needs in an MVVM scenario is a DataContext, meaning our ViewModel. This can be set from code behind (DataContext = new MainViewModel()) but that would just null out every use of the ViewModelLocator. We’ll set the datacontext from XAML.

Code Snippet
  1. <phone:PhoneApplicationPage x:Class="SqLitePoc.View.MainPage"
  2.                             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.                             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.                             xmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP8"
  5.                             xmlns:behaviors="clr-namespace:Cimbalino.Phone.Toolkit.Behaviors;assembly=Cimbalino.Phone.Toolkit"
  6.                             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  7.                             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
  8.                             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  9.                             xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  10.                             xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
  11.                             xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
  12.                             DataContext="{Binding Main,
  13.                                                   Source={StaticResource Locator}}"
  14.                             FontFamily="{StaticResource PhoneFontFamilyNormal}"
  15.                             FontSize="{StaticResource PhoneFontSizeNormal}"
  16.                             Foreground="{StaticResource PhoneForegroundBrush}"
  17.                             Orientation="Portrait"
  18.                             SupportedOrientations="Portrait"
  19.                             shell:SystemTray.IsVisible="True"
  20.                             mc:Ignorable="d">

The key here is DataContext="{Binding Main, Source={StaticResource Locator}}" this says to the view that its datacontext is bound to a property called Main and that property lives in a resource called Locator (that resource is defined in App.xaml). Now for the page itself, the page consists of a pivot control with two pivot pages, one for entering new tasks and one for viewing a list of all the tasks that have been created so far.

Code Snippet
  1. <!--  LayoutRoot is the root grid where all page content is placed  -->
  2. <Grid x:Name="LayoutRoot" Background="Transparent">
  3.     <!--  Bindable Appbar buttons  -->
  4.     <i:Interaction.Behaviors>
  5.         <behaviors:ApplicationBarBehavior>
  6.             <behaviors:ApplicationBarIconButton Command="{Binding SaveNewTaskCommand, Mode=OneTime}" IconUri="/Assets/AppBar/save.png" Text="Save Task" />
  7.         </behaviors:ApplicationBarBehavior>
  8.     </i:Interaction.Behaviors>
  9.  
  10.     <Grid.RowDefinitions>
  11.         <RowDefinition Height="Auto" />
  12.         <RowDefinition Height="*" />
  13.     </Grid.RowDefinitions>
  14.     <phone:Pivot Title="SQLite POC" Grid.Row="1">
  15.         <phone:PivotItem x:Name="NewTask" CacheMode="{x:Null}" Header="new task">
  16.             <StackPanel>
  17.                 <TextBlock Text="Title" TextWrapping="Wrap" />
  18.                 <TextBox x:Name="TextBoxTitle"
  19.                             Height="72"
  20.                             Text="{Binding NewTask.Title, Mode=TwoWay}"
  21.                             TextWrapping="Wrap" />
  22.                 <TextBlock Text="Complete by" TextWrapping="Wrap" />
  23.                 <toolkit:DatePicker Value="{Binding NewTask.Date, Mode=TwoWay}" />
  24.             </StackPanel>
  25.         </phone:PivotItem>
  26.         <phone:PivotItem x:Name="AllTasks" CacheMode="{x:Null}" Header="all tasks">
  27.             <phone:LongListSelector ItemTemplate="{StaticResource TaskListItemTemplate}" ItemsSource="{Binding Tasks}">
  28.                 <i:Interaction.Triggers>
  29.                     <i:EventTrigger EventName="SelectionChanged">
  30.                         <command:EventToCommand Command="{Binding SelectionChangedCommand}" PassEventArgsToCommand="True" />
  31.                     </i:EventTrigger>
  32.                 </i:Interaction.Triggers>
  33.             </phone:LongListSelector>
  34.         </phone:PivotItem>
  35.     </phone:Pivot>
  36. </Grid>

First thing in this snippet is a behavior for a bindable appbar button. The default appbar is not bindable, meaning that you can’t bind the buttons Command property to an ICommand on your viewmodel. This wasn’t the case in WP7 and it still isn’t in WP8, bit of a pain. Luckily, Cimbalino toolkit gives us an ApplicationBarBehavior, allowing us to bind our ICommands to the appbar, the only trade off we need to make is that the appbar buttons won’t be visible at design time but that’s a small trade-off in my opinion. We’ll add one button in the appbar, bind it to the SaveNewTaskCommand RelayCommand in MainViewModel and appoint it the save icon. Then there’s the pivot control, first pivotitem contains a stackpanel with a textbox for entering a task title and a datepicker (courtesy of the Windows Phone Toolkit) both are bound to properties of the NewTask property on the MainViewModel. Don’t forget to set the bind mode to TwoWay so that we can update the properties from our view. The second pivot item contains a list of all the tasks. Now, in WP8 they advice us to use the LongListSelector instead of the listbox that’s all great but at least make it behave more like a listbox and not some crippled dependency property missing piece of ****. The problem lies in the SelectedItem property, myself and many other XAML devs usually create a SelectedTask property and bind it to the SelectedItem property of the ListBox, the setter of that SelectedTask property would then be used to navigate to the detailspage. That was a clean, fast solution but the LongListSelector’s SelectedItem property is not a dependency property, meaning it cannot be bound so that’s not a viable solution anymore. Second option would be to bind an ICommand to the SelectionChanged event, again a no-go. There are some implementations of the LongListSelector floating around on the internet that has a bindable SelectedItem property so that would be a solution, another one is to add an EventToCommand behavior and binding the SelectionChanged event to the MainViewModel in the behavior (that’s right Windows 8 devs, we Windows Phone devs still get behaviors out of the box). I’m going with the EventToCommand solution, only thing I haven’t solved here is that when we navigate to the detail page, navigate back to the mainpage and click the same task again it won’t do anything anymore since that item still is the selected item so the selection doesn’t change and the event doesn’t fire. A solution here would be to use the messenger to send a message to the code behind of the view to set the SelectedItem property of the LongListSelector to null.

tl;dr version: LongListSelector kind off sucks but it can be solved.

The LongListSelector is bound to the Tasks collection, the ItemTemplate is defined in the resources part of the page

Code Snippet
  1. <phone:PhoneApplicationPage.Resources>
  2.     <DataTemplate x:Key="TaskListItemTemplate">
  3.         <StackPanel>
  4.             <TextBlock x:Name="Title"
  5.                        Style="{StaticResource JumpListAlphabetStyle}"
  6.                        Text="{Binding Title}"
  7.                        TextWrapping="Wrap" />
  8.             <TextBlock x:Name="Date"
  9.                        Margin="12,0,0,0"
  10.                        Text="{Binding Date}"
  11.                        TextWrapping="Wrap">
  12.                 <Run />
  13.                 <LineBreak />
  14.                 <Run />
  15.             </TextBlock>
  16.         </StackPanel>
  17.     </DataTemplate>
  18. </phone:PhoneApplicationPage.Resources>

That gives the list a nice look (as far as I can tell that is, I really really suck at designing apps…)

Last part on this page is the appbar itself, the button are defined using the Cimbalino toolkit but we need to actually put an appbar on the page, this sits between the resources and the LayoutRoot grid.

Code Snippet
  1. <!--  Buttons are defined using the behaviors in the Cimbalino toolkit to allow a bindable appbar  -->
  2. <phone:PhoneApplicationPage.ApplicationBar>
  3.     <shell:ApplicationBar IsMenuEnabled="True" IsVisible="True" />
  4. </phone:PhoneApplicationPage.ApplicationBar>

And that’s it for the MainPage, on to the final part of this post, the EditPage.xaml

First, the datacontext

Code Snippet
  1. DataContext="{Binding Edit, Source={StaticResource Locator}}"

Then the appbar buttons, again using Cimbalino (these need to sit in the LayoutRoot grid)

Code Snippet
  1. <!--  Bindable Appbar buttons  -->
  2. <i:Interaction.Behaviors>
  3.     <behaviors:ApplicationBarBehavior>
  4.         <behaviors:ApplicationBarIconButton Command="{Binding UpdateTaskCommand, Mode=OneTime}" IconUri="/Assets/AppBar/save.png" Text="Save Task" />
  5.         <behaviors:ApplicationBarIconButton Command="{Binding DeleteTaskCommand, Mode=OneTime}" IconUri="/Toolkit.Content/ApplicationBar.Delete.png" Text="Save Task" />
  6.     </behaviors:ApplicationBarBehavior>
  7. </i:Interaction.Behaviors>

And then there’s the controls

Code Snippet
  1. <!--  TitlePanel contains the name of the application and page title  -->
  2. <StackPanel Grid.Row="0" Margin="12,17,0,28">
  3.     <TextBlock Style="{StaticResource PhoneTextNormalStyle}" Text="SQLite POC" />
  4.     <TextBlock Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" Text="Edit Task" />
  5. </StackPanel>
  6.  
  7. <!--  ContentPanel - place additional content here  -->
  8. <Grid x:Name="ContentPanel"
  9.       Grid.Row="1"
  10.       Margin="12,0,12,0">
  11.     <StackPanel Margin="0,0,0,76">
  12.         <TextBlock Text="Title" TextWrapping="Wrap" />
  13.         <TextBox x:Name="TextBoxTitle" Height="72" Text="{Binding SelectedTask.Title, Mode=TwoWay}" TextWrapping="Wrap" />
  14.         <TextBlock Text="Complete by" TextWrapping="Wrap" />
  15.         <toolkit:DatePicker Value="{Binding SelectedTask.Date, Mode=TwoWay}" />
  16.     </StackPanel>
  17. </Grid>

That’s all pretty much the same as in the MainPage. And with that our small SQLite POC is finished.

Conclusion

In this post I’ve discussed SQLite in a Windows Phone 8 app. What you should take away from this is that as of Windows Phone 8 SQLite is a first class citizen, even more so when using the excellent sqlite-net library. Don’t forget to switch the platform when running on emulator or on a device, this is necessary because SQLite is a C++ library. I’ve also talked a bit about MVVM Light and the way I use it, I don’t claim that this is the best / only way to use the excellent MVVM implementation by Laurent Bugnion but it is one I feel comfortable with and that gives me great results. If you have any questions / remarks, feel free to drop a comment!

 

UPDATE:

for the LongListSelector, you can also use an extension of the control instead of defining a trigger, see http://stackoverflow.com/questions/14586521/bind-viewmodel-to-item-from-longlistselector-in-datatemplate/14600157#14600157 for more detail.
thanks for the tip Glenn (link to Glenn’s Twitter)!


Tags:

.Net | Binding | MVVM Light | Metro | Patterns | WP8 | WP7 | XAML

Comic Organizer Part III: MainViewModel and Facade pattern

by Nico

Last time we did some Xaml work to setup the metro style that will be used throughout the application, now it’s time to dive into some C# code. In this part we’ll start adding some properties to the MainViewModel that can be used for databinding and we’ll talk a bit about the Façade pattern, the first of the design patterns that we’ll try to implement.

 

ViewModel

To show data in the views of an MVVM application we need some bindable properties. Those properties are called bindable because they can be bound to a control on the view, for example a string property can be bound to a textbox so that the value of the string is shown as the textbox.Text property. Or the other way around, or both ways. Creating those properties works in the same way you’d create a property in any class but they can’t be auto properties, you need to create them the old-fashioned way. For the moment I need two properties, a string that will contain the text that a user typed into the searchbox and a list that will contain the searchresults.

Code Snippet
  1. private string searchString;
  2. public string SearchString
  3. {
  4.     get { return searchString; }
  5.     set
  6.     {
  7.         searchString = value;
  8.         RaisePropertyChanged(SearchStringPropertyName);
  9.     }
  10. }
  11.  
  12. private Response searchResult;
  13. public Response SearchResult
  14. {
  15.     get { return searchResult; }
  16.     set
  17.     {
  18.         searchResult = value;
  19.         RaisePropertyChanged(SearchResultPropertyName);
  20.     }
  21. }

“Wait, I thought you said one of them would be a list?”
Yes I did
“But I see no list”
Deceiving looks can be my young Padawan.

“Response” is a class I build that contains the list I previously mentioned, it’s in a separate class so that later on I can use the MVVM Light messenger to pass it around, the messenger won’t pass around a list so this is a work-around, more about that when we get to that.

 

Domain Project

The response classed is declared in a separate project, I’ve added a C# class library to the solution and called it “ComicOrganizer.Domain”. It will contain all the classes I’ll be needing, for now it just contains the Response class

The Response class looks like this:

Code Snippet
  1. public class Response
  2. {
  3.     public int NumberOfPageResults { get; set; }
  4.     public int StatusCode { get; set; }
  5.     public string Error { get; set; }
  6.     public IList<SearchResult> Results { get; set; }
  7.     public int Limit { get; set; }
  8.     public int Offset { get; set; }
  9.     public int NumberOfTotalResults { get; set; }
  10. }

So it has a few more properties than just a list, but we’ll need them later. These can be auto properties because we won’t be binding them to a control in the view.

The application will be using a normal List<T> but I’ve declared it here as an IList<T> so that, if we in the future build our own list, based on IList<T> we won’t need to adapt our class. Working with interfaces instead of implementations is also a best practice and helps utilising the Open/Close principle.

The IList expects members of type “SearchResult”, which is also one of my homecooked classes. A small background before we dive into that one. The purpose here is to accept a searchstring by the user, send the string to the Comicvine api, which returns the result as a JSON object (more about that later). We deserialize the JSON object in objects that our application can understand and pass it to the ViewModel. A JSON result returned by ComicVine looks like the Response class above, it states how many pages it contains (20 items per page), it has a StatusCode which is 0 if everything went peachy, if it hasn’t it sends the error. It has an array with 20 results, a total results and an Offset. With the offset we can ask the API for results 0-20 or 20-40 and so on.

The results themselves look like the SearchResult class I’ve build:

Code Snippet
  1. public class SearchResult : IResource
  2. {
  3.     public Publisher PublishedBy { get; set; }
  4.     public Image Images { get; set; }
  5.     public string Name { get; set; }
  6.     public string ApiDetailUrl { get; set; }
  7. }

As you can see this class implements the IResource interface, which is just an empty interface, the use will become clear later on. Also the Image type used here isn’t the .net Image type, it’s again a custom class, just like Publisher.

Code Snippet
  1. public class Image : IResource
  2. {
  3.     public string IconUrl { get; set; }
  4.     public string MediumUrl { get; set; }
  5.     public string TinyUrl { get; set; }
  6.     public string SmallUrl { get; set; }
  7.     public string ThumbUrl { get; set; }
  8.     public string ScreenUrl { get; set; }
  9.     public string SuperUrl { get; set; }
  10. }
  11.  
  12. public class Publisher : IResource
  13.     {
  14.     public string LocationCity { get; set; }
  15.     public string LocationState { get; set; }
  16.     public string LocationAddress { get; set; }
  17. }

And that’s all the classes we need for now. The returned JSON contains a whole lot more information but we won’t be using that, so we filter it out.

 

Facade Pattern

The Façade Pattern according to dofactory.com:

Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use.

The façade pattern creates some sort of API on top of an API, there are many reasons to do so. In our case it’s because the Comicvine API is very big and we only need a portion of it, also the Comicvine API returns JSON results, we need .net objects. So we create a wrapper around it, this wrapper is called the Façade pattern.

I’m going to start with just one method in the façade pattern, we will expand it as this series moves along. For starters I created an interface called IApi, the interface has one method called SearchVolume. This will search the Comicvine database for all comic series (called Volumes by Comicvine) that contain the searchstring the user entered. The interface looks like this:

Code Snippet
  1. public interface IApi
  2. {
  3.     void SearchVolume(string searchString);
  4. }

It accepts the searchstring but doesn’t return any value because getting the info will happen asynchronously and we will return the result by using the MVVM Light Messenger.

Now, why would I want to use an interface for my façade pattern? Let’s say that in a few months I run against another comicsite that offers an api that I want to include in my application. I can just build a second façade that again implements the interface but talks to the new API. I don’t have to adjust any logic in my view or viewmodel because it uses all the same methods and returns the same types, pretty cool huh?

Okay, let’s implement the interface in a class called ComicVineApi

Code Snippet
  1. public class ComicVineApi : IApi
  2. {
  3.     public void SearchVolume(string searchString)
  4.     {
  5.         string completeUrl = ComicVineConstants.Url + "search/" + ComicVineConstants.Key + "&query=" + searchString + "&resources=volume" + "&field_list=" + ComicVineConstants.VolumeFields + ComicVineConstants.Format;
  6.  
  7.         Download(completeUrl);
  8.     }
  9.  
  10.     private void Download(string url)
  11.     {
  12.         WebClient client = new WebClient();
  13.         client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(ClientDownloadDetailStringCompleted);
  14.         client.DownloadStringAsync(new Uri(url));
  15.     }
  16.  
  17.     private void ClientDownloadDetailStringCompleted(object sender, DownloadStringCompletedEventArgs e)
  18.     {
  19.         if (e.Error == null && !e.Cancelled)
  20.         {
  21.             JsonSerializer jsonrep = new JsonSerializer();
  22.  
  23.             string json = e.Result;
  24.             Response response = new Response();
  25.  
  26.             response = jsonrep.ConvertJson(json);
  27.  
  28.             Messenger.Default.Send<Response>(response);
  29.         }
  30.         else
  31.         {
  32.             MessageBox.Show(e.Error.Message);
  33.         }
  34.     }
  35. }

So what happens here? In the SearchVolume method we build the url that contains the Comicvine API request. a complete url looks like this:

http://api.comicvine.com/search/?api_key=1234f&query=hulk&resources=volume&field_list=api_detail_url,count_of_issues,description,
image,name,start_year,site_detail_url&format=json

I removed my API key from the URL for obvious reasons, if you want to test this link out you can request your own API key at http://www.comicvine.com it’s completely free.

The ComicVineConstants is a class where I put most of my so called magic strings, strings hard coded in the application.

Code Snippet
  1. public class ComicVineConstants
  2. {
  3.     public const string VolumeFields = "api_detail_url,count_of_issues,description,image,name,start_year,site_detail_url";
  4.     public const string Key = "?api_key=1234";
  5.     public const string Url = "http://api.comicvine.com/";
  6.     public const string Format = "&format=json";
  7. }

Again, the API key is removed from this code for obvious reasons.

So once the url is build it’s passed into the download method which will start an asynchronous download by using a WebClient instance. After that the application continues to run while the JSON results are downloaded on the background, once the download is complete the DownloadStringCompletedEventHandler will fire. The eventhandler deserialises the JSON into .net objects by using JSON.net, which is available on NuGet, and sends it on it’s way.

The Messenger class is part of the Galasoft.MvvmLight.Messaging assembly. In the eventhandler we say that we want to send an object of type “Response” on the instance called “Default” of the Messenger class. Now every class that has registered to messages of type “Response” will receive the message and can act accordingly. The Messenger class helps the separation of concerns here by allowing us to send the result to any instance of any class available, without it we would have to do the download logic in the ViewModel and that just feels plain wrong.

I will end this part here. In part IV we will start building some UI, do some databinding and register our MainViewModel to the Messenger class. And we will finally start receiving some data from the Comicvine API so we can see our façade pattern in action, until then: Live long and prosper!


Tags:

.Net | WPF | Patterns | MVVM Light

  Log in

About the author

Hi,

My name is Nico, I’m an MVP Windows Platform Development living in Belgium.
I’m currently employed as a .NET consultant at RealDolmen, one of Belgium’s leading IT single source providers.

I'm also founding member and board member of the Belgian Metro App Developer Network, a user group focussed on Windows 8 and Windows Phone development. If you're in Belgium feel free to drop by if we're doing an event. http://www.madn.be

Since June 2012 I'm a proud member of Microsoft's Extended Experts Team Belgium. And in February 2013 I became a member of DZone's Most Valuable Bloggers family.

In 2013 I became a book author and wrote "Windows 8 app projects, XAML & C# edition".

In 2014 I received the MVP award for the very first time.

I hope to get feedback from my readers either through comments, mail (nico_vermeir@hotmail.com), twitter, facebook, …

 

mvp

 

mvp

 

 

MeetLogo

 

MVBLogo

mybook

 

Month List