Nico's digital footprint

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

Using the Surface Dial as a debug tool

by Nico

Update: here’s a small video of the extension in action

 

The Surface Dial is a nifty little device, it feels great and can add some nice capabilities to your apps. However, the very best thing about it is that is has an API. I had a go with it and decided to try and turn the dial into a debugging device.

The goal

The Dial has a few gestures. It’s a button that you can press, and it rotates clockwise and counter-clockwise. My goal was to start a debugging session by clicking the Dial, Step-Over (F10) by rotating clockwise and Step-Into (F11) by rotating counter-clockwise.

Pre-requisites

We’ll need some stuff to get going:

Setting up a Visual Studio Extension

To start creating a Visual Studio Extension, launch Visual Studio 2015 and start a new project. If the SDK is installed correctly there should be an Extensibility option with a VSIX Project template.

The project it creates is basically an empty box, just some boilerplate code to have a VSIX installer and have it install your extension in VS. To start adding some functionality to the extension we need to add an extra item, in this case it will be a package, these are added as a new item into the project.

Almost ready, all we need to add next is when our extension should load. We’re going to choose for load on solution load in this sample. This is done by adding an attribute on the package class.

Thrown together, we get:

 

If you press F5 now, an experimental instance of Visual Studio should launch, with the extension installed.

Connecting to the Dial

This was the hardest part of the project, the Dial API is done in UWP. This is how we can grab the Dial instance in UWP (currently only one dial is supported per system)

var controller = RadialController.CreateForCurrentView();

The problem here is not the fact that it’s a UWP API, we can use those from win32. The problem is that the CreateForCurrentView() method requires a handle to the current window, a UWP window, which we obviously don’t have. I found the solution for this in one of the official Microsoft samples. They have a sample in the windows-classic-samples repository that shows how to access the Dial from a WinForms application.

I took the RadialControllerInterop class from that sample and added it to the extension. however, as it turned out, it was only part of the solution.

The interop interfaces actually reference the RadialController class that lives in Windows.UI.Input, a UWP namespace that we currently have no reference to. That’s where the UwpDesktop NuGet package comes in. This package makes it easy to reference UWP classes from win32 style applications. Once added through NuGet we can add the Windows.UI.Input namespace to the interop class.

We’ve got everything in place to connect to the Dial from Visual Studio.

Glueing it together

Back to the package class, there should be an Initialize method, overridden from the base class. This is where we’ll hook everything up.

First thing we’ll do is grab hold of the current Visual Studio instance, which is a DTE object. We keep a reference to this object in a field because we’ll need it later.

Next up is connecting to the Dial

In this method we’re using interop to get access to the UWP RadialController class via the interface we took from the classic windows samples. As a handle for the windows we pass in the handle for our current Visual Studio instance which we can get to from the DTE object. At this point we got a reference to the Dial that is connected to our system.

The Dial has a radial menu that we can hook into and add or remove items from it. We’ll add a Debug item to it.

I’m doing this through a list just in case I ever want to add more items, but at the moment I’m only adding one. A RadialControllerMenuItem is created via the CreateFromKnownIcon method. First parameter is the text that will be displayed in the menu, the second one is an enum value from an enum that contains some known menu icons. A RadialController has a menu property that has a collection of items, all we need to do is add our items to that collection and it will show up in the radial menu.

Final step is adding the event handlers and calling the debugger methods to let the Dial step through the code.

As you can see, the events coming from the dial are very straightforward, there’s a ButtonClicked and a RotationChanged event.

Here’s what we need to do to start debugging on button click:

The Visual Studio SDK provides an easy to use API surface. We can use the DTE.Application.Debugger class to control the debugger. The Go() method launches a debug session, the Stop() method, well, stops a debugging session.

Next, we’ll handle the rotation events

From the args we get the rotation delta, one step on the rotator is a delta of 10, +10 clockwise and –10 counter-clockwise.

And that’s it, build it in release mode and the bin/release folder will contain a .vsix installer file. Close VS, install the extension, reopen VS, open a solution, select Debug from the radial menu and debug away!

The source code is on GitHub. Here’s a link to the compiled VSIX file.

Disclaimer: the code is provided as-is. I do not plan to publish this on the gallery or maintain the project. Do feel free to pick this up and create an open-source project from it (would be nice to include a reference to this post in the description Smile)

happy coding!


Tags:

The future of XAML Styler

by Nico

A while ago I forked the popular Visual Studio plugin XAML Styler. The original author had abandoned the project before Visual Studio 2013 came out. I forked the project, added VS2013 support and starting improving / extending the extension. Over time I had a lot of help from different people. Popularity grew very fast.

But as things tend to go with hobby projects, life got in the way and I started neglecting the plugin. Pull Request stood open for over a year, reported issues weren’t responded to and the project seemed abandoned. My apologies for this. One of the things that came out of this was a new fork called XAML Magic. Dave, the maintainer of XAML Magic, took XAML Styler and did some cool things with it, like adding command line support.

About two weeks ago I felt it was about time to dive back into XAML Styler, clean up all outstanding issues and dedicate a set amount of time to the extension, and this time make sure that it remains alive. Version 2.0 was released, I got in touch with one of my best contributors, Philip, and together we started discussing the future of XAML Styler.

A few days later, Dave, the creator of XAML Magic, reached out to me. He had no plans to be a competitor to XAML Styler and wanted to work together to create one amazing plugin instead of two competing products (that’s open source spirit right there!). We added Philip into the mix and decided to switch XAML Styler over to a Github Organization.

Introducing Xavalon

The three of us created Xavalon. Xavalon is the organization that will house XAML Styler from now on (and who knows what more great products will sprout here). Moving to an organization mainly means that the product will no longer be abandoned if one of us gets other priorities. We will always have someone available to work on the extension, and obviously we will still accept Pull Requests.

So where do we go from here? We just pushed XAML Styler 2.1 out to the Visual Studio Gallery. This should fix a bug where the extension was no longer useable in VS2013 and adds Blend 2015 support! (thanks Microsoft for the help on this one!). From now on we would like to ask you to report all issues to the Xavalon repository and no longer use the repository on my github. Next steps: we’ll create a backlog of features we want to implement (starting with back-porting XAML Magic), feel free to add to our backlog as well, we’re open to all suggestions!

Thank you all for your continued support, I’m sure that Dave, Philip and myself can keep this extension in active development and we can build something amazing out of it.

https://github.com/Xavalon/XamlStyler


Tags:

HttpClient in mobile apps

by Nico

I’ve been seeing a lot of discussions lately on how to correctly use HttpClient in mobile apps, both UWP and / or Xamarin apps. In this post I’d like to share how I currently use HttpClient in my apps.

Read this first -> Disclaimer

This article discusses how I use the HttpClient class. If you use it in a different way or don’t agree with what I write here, feel free to start a constructive discussion in the comments. I’ll be happy to discuss your way of thinking vs mine and adjust the article where necessary.

To single-instance or to multi-instance

Back when I was getting into writing mobile apps (in the WP7 era) I started learning about REST services and how to call them from .NET code. I learned about HttpClient and quickly found out that it implemented IDisposable, so the logical step was the using keyword.

Turns out, not the best way to go at it. When you dispose an HttpClient instance, the connection to the server is closed.
When you do the next call to the server, with a new HttpClient instance, that connection is reopened. This causes delay in getting a response from the webservice. If a server really doesn’t want you to keep your connection open, it will inform us of that via a header and the HttpClient instance will quietly close the connection and reopen it the next time.

So, how do we create an easy to (re)use instance?

And to use this instance:

Use a base URL (and don’t even dare making it a magic string)

The HttpClient class has a base url property. As you might have figured out, that property is meant to contain the root url of your API. So if we modify our HttpClient a bit we get this

As for the magic strings remark, put all your  string values into a constants class (or whatever you want to name it, as long as they’re all together). If you don’t understand the reasoning behind this, just try writing applications with string values in the code, you’ll find out soon enough Smile

Use compression where possible

Since we’re mostly writing mobile applications we need to keep data usage in mind. We have no idea if our users will have an expensive data plan or unlimited data or if they’re on WIFI. This means that it’s our job as developers to keep the data usage as low as possible. The quickest win here is to compress the data from the server and decompress it on the device, this of course means that the server needs to support compression. If you yourself maintain the server, make sure that it is enabled (it’s enabled by default in Web API). Once that is enabled, we need to tell the HttpClient to enable decompression from either Deflate or Gzip formats. Enable decompression is done through an HttpClientHandler object that we can pass into the HttpClient constructor.

Caching

Another often overlooked way of limiting data usage is caching. You’d be surprised of the times users request the same data, if we cache the API result we can just fetch it from that cache again. Extra usability feature here is that we can actually show results when the device is offline. You can write your own caching framework if you want, or use one of the existing ones. I tend to switch between Q42 (they save cached data in JSON files) and Akavache (they save cached data in SQLite).

Security Tokens

We often need to make API calls to secured services. To do this we need to go through some form of authorization / authentication flow where we get an access token from (a bearer token for example). That token needs to be passed in with every API call we make. Since we’re now using a single instance for our HttpClient, it would be nice to specify the token once and be done with it. This an easily be done by using the default headers. HttpClient contains a collection of headers that it will use with every call it makes. This is how you add a Bearer token for example:

Use ConfigureAwait(false)

HttpClient is an async library. This means that we usually use this in a method that returns either Task or Task<T>. This also means that if you don’t use ConfigureAwait(false) that you’ll create quite a lot of context switching. When you await an async method, and don’t specify ConfigureAwait(false), the method will do it’s thing on the thread pool and switch back to the caller’s context when finished. This is exactly the behavior that you want when you request a webresult and immediately put the data into a property that is bound against, since binding happens on the UI thread. But this is not what we want when we’re executing code in a library or in a service class, so that’s where we’ll use ConfigureAwait(false).

Let’s say, for example, that we have a method to fetch all resources as a JSON string. The correct way of using ConfigureAwait(false) would be:

The FetchData method doesn’t use ConfigureAwait(false) because it needs to return to the caller context. The caller context here is the UI thread. The property that the returned value is being set to will trigger a change notification, so we need to be on the UI thread.

The FetchAllResources method has two calls that are awaited, by not returning to caller context in that method we prevent two context switches to occur.

(Xamarin only) use ModernHttpClient

Xamarin allows us to write iOS and Android applications in C#. We can use the HttpClient for that but we'd be using an abstraction of the lowest common denominator of both platforms. If you use ModernHttpClient on those platforms instead, you will get the full networking stack of the respective platforms. (thanks for reminding me @Depechie)

Conclusion

In this post I discussed some techniques with using HttpClient to fetch data in mobile applications that I’ve picked up over the years. As I’ve mentioned in the disclaimer, this is what I’m doing today and what feels right to me. Feel free to let me know if you do things another way, if you can convince me that your way is better, I will have learned something and will update the post accordingly Smile.


Tags:

.Net | Xamarin

Xamarin Forms Bindable Wrappanel

by Nico

A wrappanel is something XAML developers are very familiar with. It’s a panel that orders its children either horizontally or vertically but when the children reach the border, the panel wraps to the next row or column.

Xamarin Forms currently does not have a default implementation for something similar so I set out to find one online. To my surprise it took quite some time to find something (guess I’m spoiled by the awesome toolkits we have as Windows app devs), eventually I found the WrapLayout.

The WrapLayout works but had a disadvantage, it didn’t have an ItemsSource or DataTemplate property but I did have a solid foundation, so I went to expand the implementation.

I started by creating a bindable property for itemssource and one for item template. In MS XAML we would use Dependency properties, in Xamarin XAML it’s called BindableProperty.

   1: /// <summary>
   2: /// Backing Storage for the Spacing property
   3: /// </summary>
   4: public static readonly BindableProperty ItemTemplateProperty =
   5:     BindableProperty.Create<AwesomeWrappanel, DataTemplate>(w => w.ItemTemplate, null,
   6:         propertyChanged: (bindable, oldvalue, newvalue) => ((AwesomeWrappanel)bindable).OnSizeChanged());
   7:  
   8: /// <summary>
   9: /// Spacing added between elements (both directions)
  10: /// </summary>
  11: /// <value>The spacing.</value>
  12: public DataTemplate ItemTemplate
  13: {
  14:     get { return (DataTemplate)GetValue(ItemTemplateProperty); }
  15:     set { SetValue(ItemTemplateProperty, value); }
  16: }
  17:  
  18: /// <summary>
  19: /// Backing Storage for the Spacing property
  20: /// </summary>
  21: public static readonly BindableProperty ItemsSourceProperty =
  22:     BindableProperty.Create<AwesomeWrappanel, IEnumerable>(w => w.ItemsSource, null,
  23:         propertyChanged: ItemsSource_OnPropertyChanged);
  24:  
  25: /// <summary>
  26: /// Spacing added between elements (both directions)
  27: /// </summary>
  28: /// <value>The spacing.</value>
  29: public IEnumerable ItemsSource
  30: {
  31:     get { return (IEnumerable)GetValue(ItemsSourceProperty); }
  32:     set { SetValue(ItemsSourceProperty, value); }
  33: }

ItemTemplate is a property of type DataTemplate, ItemSource is an IEnumerable (the non-generic version). So far so good, next up is adding some logic to add the itemsource items as children of the Layout. Since the wrappanel has Layout<T> as a base there is no itemsource from the underlying control.

   1: private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
   2: {
   3:     foreach (object item in args.NewItems)
   4:     {
   5:         var child = ItemTemplate.CreateContent() as View;
   6:         if (child == null)
   7:             return;
   8:  
   9:         child.BindingContext = item;
  10:         Children.Add(child);
  11:     }
  12: }

We’re going to respond to collection changed events, hoping that whoever uses the control binds to a collection that implements INotifyCollectionChanged, like the infamous ObservableCollection<T>. We’re creating a View from the DataTemplate for every newly added item, set the BindingContext to the item itself and add it to the Children collection. The binding framework will take care of all the rest.

One step left, we need to add an event handler for the CollectionChanged event. We do this in the property changed callback of the ItemSource bindable property

   1: private static void ItemsSource_OnPropertyChanged(BindableObject bindable, IEnumerable oldvalue, IEnumerable newvalue)
   2: {
   3:     if (oldvalue != null)
   4:     {
   5:         var coll = (INotifyCollectionChanged)oldvalue;
   6:         // Unsubscribe from CollectionChanged on the old collection
   7:         coll.CollectionChanged -= ItemsSource_OnItemChanged;
   8:     }
   9:  
  10:     if (newvalue != null)
  11:     {
  12:         var coll = (INotifyCollectionChanged)newvalue;
  13:         // Subscribe to CollectionChanged on the new collection
  14:         coll.CollectionChanged += ItemsSource_OnItemChanged;
  15:     }
  16: }

If there’s a previous instance we disconnect from its event, afterwards we try to cast the itemsource to INotifyCollectionChanged, if that succeeds we know there’s a collection changed event we can hook into. One problem here, this is all static but the properties we need to use in the event handler are not so we need to find a way to get from static to non-static code, events to the rescue!

I added a static event, cool thing about those is that the event handlers can be non-static.

   1: private static event EventHandler<NotifyCollectionChangedEventArgs> _collectionChanged;

Used the constructor to hook up the handler

   1: public AwesomeWrappanel()
   2: {
   3:     _collectionChanged += OnCollectionChanged;
   4: }

And that’s it! The handler method is the one we discussed a bit earlier, where the items in the itemsource are converted into Children elements.

Here’s how to use it in XAML

   1: <controls:AwesomeWrappanel ItemsSource="{Binding Persons}" Orientation="Horizontal">
   2:     <controls:AwesomeWrappanel.ItemTemplate>
   3:         <DataTemplate>
   4:             <StackLayout BackgroundColor="Red">
   5:                 <Label Text="{Binding Name}" />
   6:                 <Label Text="{Binding Age}" />
   7:             </StackLayout>
   8:         </DataTemplate>
   9:     </controls:AwesomeWrappanel.ItemTemplate>
  10: </controls:AwesomeWrappanel>

A quick screenshot of the result:

A demo project can be found on my OneDrive or see this GitHub Gist for the Wrappanel class.

Happy coding!


Tags:

.Net | Xamarin | XAML | WinRT

Grid column behavior–Xamarin XAML vs MS XAML

by Nico

There’s a small detail difference in how rows and columns in a Grid behave in Xamarin Forms vs Microsoft XAML. A small difference but with quite a big impact. Look at the following XAML snippet (Microsoft XAML)

Code Snippet
  1. <Grid Background="Red">
  2.     <Grid.RowDefinitions>
  3.         <RowDefinition Height="50" />
  4.         <RowDefinition Height="*" />
  5.     </Grid.RowDefinitions>
  6.  
  7.     <Grid Grid.Row="1" Background="Blue">
  8.         <Grid.RowDefinitions>
  9.             <RowDefinition Height="Auto" />
  10.             <RowDefinition Height="300" />
  11.         </Grid.RowDefinitions>
  12.     </Grid>
  13. </Grid>

At runtime this looks like:

Exactly what we as seasoned XAML developers would expect.

Converted to Xamarin Forms XAML this turns into:

Code Snippet
  1. <Grid BackgroundColor="Red">
  2.   <Grid.RowDefinitions>
  3.     <RowDefinition Height="50" />
  4.     <RowDefinition Height="*" />
  5.   </Grid.RowDefinitions>
  6.   
  7.   <Grid Grid.Row="1" BackgroundColor="Blue">
  8.     <Grid.RowDefinitions>
  9.       <RowDefinition Height="Auto" />
  10.       <RowDefinition Height="300" />
  11.     </Grid.RowDefinitions>
  12.   </Grid>
  13. </Grid>

Only difference is the property name to set the background color. However, if we look at this at runtime we see a completely different story.

It looks like the inner Grid isn’t rendered at all. But let’s try to add a Label to the inner Grid.

Code Snippet
  1. <Grid BackgroundColor="Red">
  2.   <Grid.RowDefinitions>
  3.     <RowDefinition Height="50" />
  4.     <RowDefinition Height="*" />
  5.   </Grid.RowDefinitions>
  6.   
  7.   <Grid Grid.Row="1" BackgroundColor="Blue">
  8.     <Grid.RowDefinitions>
  9.       <RowDefinition Height="Auto" />
  10.       <RowDefinition Height="300" />
  11.     </Grid.RowDefinitions>
  12.     <Label Text="Hello Xamarin!" />
  13.   </Grid>
  14. </Grid>

So what exactly is going on here? The inner Grid (the blue one) doesn’t specify any columns, that means that by default there’s only one column available. In Microsoft XAML the width of that default column is set to “*” so it takes up all available space. In Xamarin Forms that width is set to “Auto” so it only takes up the space it needs. A subtle difference with a big impact.

To fix this, add a column with “*” as width

Code Snippet
  1. <Grid BackgroundColor="Red">
  2.   <Grid.RowDefinitions>
  3.     <RowDefinition Height="50" />
  4.     <RowDefinition Height="*" />
  5.   </Grid.RowDefinitions>
  6.   <Grid.ColumnDefinitions>
  7.     <ColumnDefinition Width="*" />
  8.   </Grid.ColumnDefinitions>
  9.   
  10.   <Grid Grid.Row="1" BackgroundColor="Blue">
  11.     <Grid.RowDefinitions>
  12.       <RowDefinition Height="Auto" />
  13.       <RowDefinition Height="300" />
  14.     </Grid.RowDefinitions>
  15.  
  16.   </Grid>
  17. </Grid>

result:

Conclusion

In this post I’ve shown a difference in implementation between Xamarin Forms XAML and Microsoft XAML and how to fix it.

Note that this sample is based on Xamarin Forms 1.2. Xamarin has stated that they will change the implementation in Forms 1.3 to reflect the Microsoft implementation.


Tags:

XAML | WinRT | WP8 | WPF | Xamarin

LowlandsWPDev 2014 slides & demos

by Nico

Last weekend I had the distinct honor and pleasure of co-organizing and speaking at an international Windows Platform developer event. Lowlands WP dev 2014 was a joint venture between the Dutch and the Belgian WP communities and it was awesome!

The slides and demos for my session on Background tasks can be found here:

Demos

 
PIctures of the event itself can be found here

Tags:

.Net | Community | Presenting | Talk | XAML | geofencing

A practical guide to MVVM (Light)–Part 2

by Nico

A practical guide to MVVM (Light) – Part 1

In part 1 I’ve shown you how to setup a new Windows Phone project with MVVM Light, how to hookup everything and we’ve seen what databinding is and how it works. In this part we’re going to build on that same project, delving a bit deeper into MVVM in a practical way.

Intro

In part 2 we’ll have a look at how to navigate from a list page, like the one we’ve created in part 1, to a detail page. We’ll need to inform the viewmodel on what item was clicked so that it can fetch more detailed information from the datastore. We’ll also have a look at value converters, a feature not really MVVM related but one that’s really important so I’m including it here anyway.

Navigation

There are a few ways to get navigation done in a Windows Phone app. You can use a NavigationService class for example. A class that can get injected via SimpleIoc and that has a .Navigate function, the Cimbalino Toolkit has one build-in for example. One other way to do navigation without delving into code-behind code in the view is by using Behaviors and Actions in XAML. Don’t worry, you don’t need to remember the exact syntax as long as you have Blend.

Open up the MainPage.xaml of our Part 1 project in Blend and have a look at the Assets Tab. (Quick tip: if you want to open a certain page in Blend, right-click it in Visual Studio and select “Open in Blend”, this also works for opening a page from Blend in Visual Studio).

In the Behaviors section you’ll find a bunch of Actions and Behaviors. An interesting one here is the NavigateToPageAction, drag and drop that one onto the ListBox. You’ll notice that the Action has attached itself to the ListBox if you have a look at the Objects & Timeline pane.

Before we can navigate we need to create a new page, add a page called DetailPage.xaml to the View folder of the project. Creating the page can be done from either Blend or Visual Studio. After creating the DetailPage, go back to MainPage in Blend and select the NavigateToPageAction that’s attached to the Listbox in the Objects & Timeline pane. Go to the properties.

You’ll see here that the action contains a trigger. There we can select what event from the Listbox will trigger the action, set this to SelectionChanged. In the dropdown for TargetPage you should see MainPage and DetailPage (and any other pages you might have created), set it to DetailPage and run the app. Click on an item and you’ll see that the app navigates to the detailpage. This is what the action looks like in XAML.

Code Snippet
  1. <ListBox ItemTemplate="{StaticResource PersonTemplate}" ItemsSource="{Binding Persons}">
  2.     <i:Interaction.Triggers>
  3.         <i:EventTrigger EventName="SelectionChanged">
  4.             <ec:NavigateToPageAction TargetPage="/View/DetailPage.xaml" />
  5.         </i:EventTrigger>
  6.     </i:Interaction.Triggers>
  7. </ListBox>

Loading detailed data for clicked item

When we select an item we navigate to a detail page. It would be nice to effectively show all the details. When using a ListBox this is pretty easy. We can just define a property on the viewmodel and bind the ListBox’s SelectedItem property to the property on the viewmodel. The property could look something like this

Code Snippet
  1. public Person SelectedPerson
  2. {
  3.     get { return _selectedPerson; }
  4.     set
  5.     {
  6.         if (_selectedPerson == value) return;
  7.         _selectedPerson = value;
  8.         RaisePropertyChanged(() => SelectedPerson);
  9.         LoadDetails();
  10.     }
  11. }

The binding on the ListBox would look like this

Code Snippet
  1. <ListBox ItemTemplate="{StaticResource PersonTemplate}
  2.          ItemsSource="{Binding Persons}"
  3.          SelectedItem="{Binding SelectedPerson,
  4.                                 Mode=TwoWay}">

Notice that we have to specify that this is a two-way binding. If we don’t, the property will not get updated from the view. Databinding by default is OneWay, from the viewmodel to the view.

While this is a valid way of working, it has some issues.

  • LongListSelector doesn’t support binding to SelectedItem (I described workarounds for this here and here)
  • The DetailPage needs to have MainViewModel as datacontext, which is possible and allowed but often this means that a viewmodel turns into a superclass that handles the datacontext for every view.

On to the next possibility we go!

EventToCommand

The way of passing the selecteditem from the view to the viewmodel and to the next viewmodel I’m about to describe takes a bit more setup than the previous part. However, while it is a bit more work, it’s my preferred way of working. To me this feels like the “MVVM way” but use whatever feels most comfortable for you.

Go into Blend and delete the NavigateToPageAction that is still attached to the ListBox. Go back to the Assets pane, to the list of Behaviors. You’ll find that in the list is an EventToCommand behavior. This allows us to hook up events fired by controls in the view to trigger certain actions on the viewmodel. Drag & drop the EventToCommand onto the ListBox.

Before specifying the target command for the behavior, we’ll have to add one to the viewmodel first. Windows Phone has an interface called ICommand that we can use for binding. MVVM Light comes with two implementations of ICommand called RelayCommand and RelayCommand<T>. We’re going to use the generic version RelayCommand<T> because this way we can get the event arguments into our viewmodel.

Code Snippet
  1. private RelayCommand<SelectionChangedEventArgs> _selectionChangedCommand;
  2.  
  3. public RelayCommand<SelectionChangedEventArgs> SelectionChangedCommand
  4. {
  5.     get
  6.     {
  7.         return _selectionChangedCommand ??
  8.                (_selectionChangedCommand = new RelayCommand<SelectionChangedEventArgs>(OnSelectionChanged));
  9.     }
  10. }

When using the generic version of RelayCommand we specify the type of T as the type of eventargs we’re expecting. Note that this can also be a string that’s passed in as commandparameter for example when binding to a button’s command property.

SIDENOTE – the ?? operator: If you’ve never seen the ?? operator before, it checks if whatever’s on its leftside is not null, if it is it executes whatever’s on its rightside. In this case the rightside will only get executed the very first time the command is called, that’s when the private field is instantiated.

the parameter passed into the RelayCommand<T> constructor is the action that we’ll be executing when the command is called.

Code Snippet
  1. private void OnSelectionChanged(SelectionChangedEventArgs args)
  2. {
  3.     throw new System.NotImplementedException();
  4. }

We’ll complete this in a minute, just leave it like this to make the application compile.

Bind the EventToCommand Command property to the RelayCommand either through Blend or in XAML. Make sure to check the PassEventArgsToCommand checkbox when going via Blend. This is what the XAML should look like.

Code Snippet
  1. <ListBox ItemTemplate="{StaticResource PersonTemplate}"
  2.     ItemsSource="{Binding Persons}">
  3.     <i:Interaction.Triggers>
  4.         <i:EventTrigger EventName="SelectionChanged">
  5.             <Command:EventToCommand PassEventArgsToCommand="True" Command="{Binding SelectionChangedCommand, Mode=OneWay}"/>
  6.         </i:EventTrigger>
  7.     </i:Interaction.Triggers>
  8. </ListBox>

No more SelectedItem binding. If we place a breakpoint in the OnSelectionChanged method and check the parameter you should see the selected item in there.

So far, we’re using the controls their events, using a behavior to pass the eventhandler to a command on our ViewModel. No code behind required, clean MVVM setup. The next step is to navigate to another page and pass the selected item to another viewmodel. Let’s start by navigating.

Navigating via the ViewModel

I’ve mentioned before that navigating from within the viewmodel can be done by using a NavigationService. It’s time to do just that. A NavigationService is not included in Windows Phone so we’ll either need to write one or use an existing one. I’m going to do the latter and use an existing one.

Use either NuGet or the Package manager console to add the Cimbalino Windows Phone toolkit to the project

Install-Package Cimbalino.Phone.Toolkit

Now it’s time to revisit the ViewModelLocator. Remember SimpleIoc? We used the ViewModelLocator to register services and use constructor injection to inject those services into our viewmodels. First add a using statement to the ViewModelLocator

Code Snippet
  1. using Cimbalino.Phone.Toolkit.Services;

Next, register the NavigationService in SimpleIoc. (line 14)

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.         SimpleIoc.Default.Register<INavigationService, NavigationService>();
  15.     }
  16.  
  17.     SimpleIoc.Default.Register<MainViewModel>();
  18. }

Back to the MainViewModel, we add a new parameter to its constructor.

Code Snippet
  1. private INavigationService _navigationService;
  2. public MainViewModel(IDataService dataService, INavigationService navigationService)
  3. {
  4.      _navigationService = navigationService;

Using the NavigationService is pretty easy.

Code Snippet
  1. private void OnSelectionChanged(SelectionChangedEventArgs args)
  2. {
  3.     _navigationService.NavigateTo("/View/DetailPage.xaml");
  4. }

Do be careful with the path to the page, it’s a string so no intellisense. If the page is in a folder make sure to start with “/”. Run the app, click an item. The app should navigate to the DetailPage, just like we had before. Time to add the PersonViewModel. Add a class named PersonViewModel and make it inherit ViewModelBase, that’s enough for now.

Every new viewmodel in an MVVM Light application needs to be added to the ViewModelLocator. We need to register the viewmodel in SimpleIoc and create a property to allow databinding. First register the viewmodel in the ViewModelLocator’s constructor

Code Snippet
  1. SimpleIoc.Default.Register<PersonViewModel>();

Next is the property

Code Snippet
  1. public PersonViewModel Person
  2. {
  3.     get
  4.     {
  5.         return ServiceLocator.Current.GetInstance<PersonViewModel>();
  6.     }
  7. }

Now we can set the DetailPage’s datacontext to the PersonViewModel by adding this to the opening tag of the page.

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

For your reference, here’s the complete tag

Code Snippet
  1. <phone:PhoneApplicationPage x:Class="MvvmDemo.View.DetailPage"
  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 Person,
  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">

Messaging

Now that we have two viewmodels, we need to setup a form of communication between them. Luckily for us, MVVM Light has something in place for this called the Messenger. The Messenger is a class that receives and delivers messages. One viewmodel subscribes for a certain message, the other viewmodel sends a message and the messenger makes sure it gets delivered nicely. The messenger can take any type and send it as a message, we could for example send an entire person, or the ID of a person and send it as an integer. But in a bigger app this could get complicated, imagine if 5 viewmodels start listening for integers but one is expecting the id of a product, another one expects the id of a person while a third one expects a result of some sorts. It would be a lot of work to get the subscribe / unsubscribe just right. That’s why I advice you to make it a habit to encapsulate the data in a special message class. Like for example to send our selected person over to the PersonViewModel.

Code Snippet
  1. public class PersonSelectedMessage : MessageBase
  2. {
  3.     public Person SelectedPerson { get; set; }
  4.     public PersonSelectedMessage(Person selectedPerson)
  5.     {
  6.         SelectedPerson = selectedPerson;
  7.     }
  8. }

As you can see, this is a really simple class with only one purpose: encapsulate a Person instance. The MessageBase baseclass is an MVVM Light class that contains some info about the sender and the target but I use this mainly to make the classes easier to recognize as MVVM Light messages. I also place all those message classes in a Messages folder in my project.

Let’s subscribe to this type of message from the PersonViewModel. First add a Person property to the PersonViewModel that we can bind to.

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

Then add this in the PersonViewModel constructor.

Code Snippet
  1. public PersonViewModel()
  2. {
  3.     Messenger.Default.Register<PersonSelectedMessage>(this, msg =>
  4.     {
  5.         SelectedPerson = msg.SelectedPerson;
  6.     });
  7. }

This registers our current instance of PersonViewModel to receive messages of the PersonSelectedMessage type. We will send this message from the MainViewModel in the OnSelectionChanged method that fires when selecting a person in the ListBox.

Code Snippet
  1. private void OnSelectionChanged(SelectionChangedEventArgs args)
  2. {
  3.     _navigationService.NavigateTo("/View/DetailPage.xaml");
  4.     Messenger.Default.Send(new PersonSelectedMessage(args.AddedItems[0] as Person));
  5. }

If you set a breakpoint in the action that fires when a message arrives and try to select a person the first time it will probably fail. This is because the message departs before the PersonViewModel has had a chance to initialize and register for the message, it will be sent but it will never arrive. If you hit the back key back to the MainPage and select another person it will arrive because the PersonViewModel instance already exists and is listening to the message. The quickest (and easiest) way to fix this is to make sure that PersonViewModel is initialized when the app launches. We can use an overload of SimpleIoc’s register method for this.

In the ViewModelLocator, add true as a parameter to the registration

Code Snippet
  1. SimpleIoc.Default.Register<PersonViewModel>(true);

This will initialize the class at the moment of registration and it will register itself as a subscriber for the PersonSelectedMessage. After binding the page title to SelectedPerson.Name and running the app this is the result:

If this was a real application you would use the action of the messenger to fetch the detailed information of the selected item. DataBinding takes care of displaying the data on screen.

Conclusion

In this second part of my practical guide to MVVM Light I’ve discusses the way I usually work to select an item from a list, navigate to a detail page and fetch / show detailed information.

Some more MVVM related articles:

Some more in depth IOC/DI articles:

Feel free to ping me on Twitter (@NicoVermeir) should you have any questions.

The code for this second part can be found on OneDrive.


Tags:

.Net | Binding | MVVM Light | Metro | Silverlight | WP7 | WP8 | WPF | WinRT | Windows 8 | XAML

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

Win Store: SuspensionManager failed

by Nico

While implementing tombstoning in a Windows Store app I recently ran into this issue. Some pages tombstoned and resumed perfectly, while some other pages gave this error when tombstoning

This one took me a while to figure out, but I finally found the problem. But before diving into the solution, I’ll show you how I got to this error.

Tombstoning

If you’re reading this, I’m assuming you know about the app lifecycle and tombstoning so I’m not going to explain that. To demonstrate the problem I created a blank app, added in a basic page so that Visual Studio included the NavigationHelper and SuspensionManager classes.

In the app I have two pages, Mainpage.xaml and Page2.xaml. Mainpage has a button that takes me to Page2. The navigation happens with the build-in NavigateToPageAction, easily dragged and dropped onto the button from Blend.

This creates an EventTriggerBehavior on the button that triggers a NavigateToPageAction

All that’s left to do is set the target page in the NavigateToPageAction properties

And we’re done. We’ve just created an app with a button that navigates to another page without writing any code, pretty neat and easy stuff right?

Next thing I did was follow this MSDN article that shows in a few easy steps how to implement tombstoning so that if the app tombstones on a certain page and the user switches back to the app, it reloads that page. It worked and all was well. That is, until I implemented the tombstoning on a page that was navigated to using the NavigateToPageAction. tombstoning that page always resulted in the error shown in the screenshot at the beginning of this post (and it took me a few hours to discover that the action was at fault here). Let’s have a closer look to see what’s actually happening here.

Navigation and NavigationParameters

When navigating between pages we can pass parameters. In Windows Store the signature of the Frame.Navigate function is this

Navigate(Type)
Navigate(Type, Object)
Navigate(Type, Object, NavigationTransitionInfo)

The parameter is of type Object, meaning we can pass in anything we’d like. Pretty powerful right? Right, except when tombstoning.

At a certain point in the Tombstoning process this snippet of code gets executed

Code Snippet
  1. private static void SaveFrameNavigationState(Frame frame)
  2. {
  3.     var frameState = SessionStateForFrame(frame);
  4.     frameState["Navigation"] = frame.GetNavigationState();
  5. }

This will save the current NavigationState of the pages into a dictionary. The caveat here is that this only works with primitive types. If we pass strings or integers as parameter this will work, no problem. If we pass in an object of type MyClass we will get the SuspensionManager failed error.

Okay cool, that’s all great, we found a possible source of the error. But, we’re not passing in any parameters to the page, so why are we getting the error? Let’s set a breakpoint in the OnNavigatedTo method in Page2.xaml.cs

Well well, would you look at that. Our NavigateToPageAction snuck in a little parameter without telling us, and that parameter is not a primitive type so we get a crash.

The fix + conclusion

The fix is actually really easy, don’t use NavigateToPageAction. Yes just don’t use it. I know it’s really fast and easy but it breaks the entire tombstoning thingy. I fixed it by calling Frame.Navigate (Type) from the button’s click event.

I’ve uploaded a sample with two buttons on my OneDrive, one button has the crashing effect, the other one doesn’t.

Download Link


Tags:

.Net | Windows 8 | WinRT | XAML | tombstoning | lifecycle

A custom button that disappears in snapped mode

by Nico

I’m currently working on a Windows 8.1 app that has quite some buttons in the app bar. The buttons are not positioned next to each other in one row and are not all the same size. This means that I can’t use the new CommandBar to auto-hide some buttons whenever the app gets snapped to the side. That means that it’s time for a custom button.

Actually, I have two solutions to this problem. One that puts the hide/show functionality in the button and one that puts it in the page where you use the appbar.

The one with functionality in the button

Create a new class and let it derive from Button.

Code Snippet
  1. public class CustomAppBarButton : Button
  2. {
  3.     public static readonly DependencyProperty HideOnSnapProperty = DependencyProperty.Register(
  4.         "HideOnSnap", typeof (bool), typeof (CustomAppBarButton), new PropertyMetadata(default(bool)));
  5.  
  6.     public bool HideOnSnap
  7.     {
  8.         get { return (bool) GetValue(HideOnSnapProperty); }
  9.         set { SetValue(HideOnSnapProperty, value); }
  10.     }
  11.  
  12.     public CustomAppBarButton()
  13.     {
  14.         HideOnSnap = false;
  15.  
  16.         Window.Current.SizeChanged += CurrentOnSizeChanged;
  17.     }
  18.  
  19.     private void CurrentOnSizeChanged(object sender, WindowSizeChangedEventArgs windowSizeChangedEventArgs)
  20.     {
  21.         if (!HideOnSnap)
  22.             return;
  23.  
  24.         var size = Window.Current.Bounds;
  25.  
  26.         if (size.Width <= size.Height)
  27.         {
  28.             Visibility = Visibility.Collapsed;
  29.         }
  30.         else
  31.         {
  32.             Visibility = Visibility.Visible;
  33.         }
  34.     }
  35. }

First thing we need is a dependency property so we can specify whether or not we want to hide a button in snapped view. From the constructor we subscribe to the SizeChanged event of the current window. Whenever that event fires every button will check if it needs to hide. If HideOnSnap is enabled, the buttons will check if the app is currently snapped by checking if the width of the window is smaller than the height.

To use this control, and let the button hide on snap you can use something like this

Code Snippet
  1. <local:CustomAppBarButtonType1 Content="Button1" HideOnSnap="False" />
  2. <local:CustomAppBarButtonType1 Content="Button2" HideOnSnap="True" />

This works peachy, but if you have an appbar with multiple of these buttons and run on a slower system you might experience some delay when opening up the appbar for the first time. All buttons are getting created and are attaching the event handler so depending on the amount of buttons it might take some time.

If you experience the delay, option 2 might work better

The one where the page handles it

This option also needs a custom button class but it’s a much smaller one

Code Snippet
  1. public class CustomAppBarButton : Button
  2. {
  3.     public static readonly DependencyProperty HideOnSnapProperty = DependencyProperty.Register(
  4.         "HideOnSnap", typeof (bool), typeof (CustomAppBarButton), new PropertyMetadata(default(bool)));
  5.  
  6.     public bool HideOnSnap
  7.     {
  8.         get { return (bool) GetValue(HideOnSnapProperty); }
  9.         set { SetValue(HideOnSnapProperty, value); }
  10.     }
  11.  
  12.     public CustomAppBarButton()
  13.     {
  14.         HideOnSnap = false;
  15.     }
  16. }

No event handling in this class, just a dependency property to specify whether or not it needs to hide. The actual hiding and showing of the buttons happens in the page itself.

Code Snippet
  1. public MainPage()
  2. {
  3.     InitializeComponent();
  4.     SizeChanged += OnSizeChanged;
  5. }
  6.  
  7. private async void OnSizeChanged(object sender, SizeChangedEventArgs sizeChangedEventArgs)
  8. {
  9.     var size = Window.Current.Bounds;
  10.     var dispatcher = Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher;
  11.  
  12.     if (size.Width <= size.Height)
  13.     {
  14.         await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, HideAllHideableButtons);
  15.     }
  16.     else
  17.     {
  18.         await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, ShowAllHideableButtons);
  19.     }
  20. }

We register for the SizeChanged event of the page (event comes from the FrameworkElement class, a page in Windows 8.1 derives from that class). The rest of the code is very similar from the code in the buttons. A difference is that we need to use the dispatcher here to marshall the hiding / showing of the buttons to the UI thread.

Here’s the code to hide all hideable buttons (note that you have to name your appbar, mine is called AppBarBottom

Code Snippet
  1. private void HideAllHideableButtons()
  2. {
  3.     var buttons = AppBarBottom.FindDescendantsByType<CustomAppBarButtonType2>().Where(b => b.HideOnSnap);
  4.  
  5.     foreach (var appBarButton in buttons)
  6.     {
  7.         appBarButton.Visibility = Visibility.Collapsed;
  8.     }
  9. }

We’re looking for all controls on the page that are of type CustomAppBarButton and that have HideOnSnap set to true (don’t worry about the FindDescendantsByType function, that’s an extension method, I’ll come back to it in a minute).

Every button that we found, we set to collapsed and voila, buttons are hidden when snapped. Getting them to show up again is very (very) similar

Code Snippet
  1. private void ShowAllHideableButtons()
  2. {
  3.     var buttons = this.FindDescendantsByType<CustomAppBarButton>().Where(b => b.HideOnSnap);
  4.  
  5.     foreach (var appBarButton in buttons)
  6.     {
  7.         appBarButton.Visibility = Visibility.Visible;
  8.     }
  9. }

As for the FindDescendantsByType<T> extension method:

Code Snippet
  1. public static IEnumerable<T> FindDescendantsByType<T>(this DependencyObject depObj) where T : DependencyObject
  2. {
  3.     if (depObj != null)
  4.     {
  5.         for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
  6.         {
  7.             DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
  8.             if (child != null && child is T)
  9.             {
  10.                 yield return (T)child;
  11.             }
  12.  
  13.             foreach (T childOfChild in FindDescendantsByType<T>(child))
  14.             {
  15.                 yield return childOfChild;
  16.             }
  17.         }
  18.     }
  19. }

this will look through the visual tree in search for elements of the specified type (I think I found this method on SO somewhere, forgot the exact link but this is not my code).

Usage is exactly the same as with the first type of button.

Code Snippet
  1. <local:CustomAppBarButtonType2 Content="Button1" HideOnSnap="False" />
  2. <local:CustomAppBarButtonType2 Content="Button2" HideOnSnap="True" />

Conclusion

In this post I’ve discussed two ways of creating a custom button that can hide itself when the application gets snapped to the side, allowing for a quick way to create an adaptable application bar.

You can find a demo application using both ways of working on my OneDrive (Top appbar uses first type, bottom appbar uses second type).


Tags:

.Net | WinRT | Windows 8 | XAML

  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