Nico's digital footprint

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

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

Geofencing in Windows Phone 8.1

by Nico

Windows Phone 8.1 brings the concept of Geofencing to our beloved Windows Phone platform. Geofencing allows us to trigger an action whenever a user is at a predefined set of coordinates. Windows Phone 8.1 registers geofences with the OS so our app doesn’t need to run for triggers to fire. For this post we’ll trigger a welcome message whenever someone is at building 9 of the Microsoft Redmond campus.

The app

Create a new Windows Phone 8.1 app. Add the Location capability in the Package.appxmanifest. We obviously need location capabilities for this Glimlach

Let’s dive into code. This app will only have a blank MainPage and a message dialog that pops up when we’re near building 9.

First thing we need is a reference to the current GeofenceMonitor.

Code Snippet
  1. GeofenceMonitor _monitor = GeofenceMonitor.Current;

Setting the Geofence location and hooking up the event happens in the constructor

Code Snippet
  1. public MainPage()
  2. {
  3.     InitializeComponent();
  4.  
  5.     _monitor.GeofenceStateChanged += MonitorOnGeofenceStateChanged;
  6.  
  7.     //Microsoft Redmond building 9
  8.     BasicGeoposition pos = new BasicGeoposition { Latitude = 47.6397, Longitude = -122.1289 };
  9.  
  10.     Geofence fence = new Geofence("building9", new Geocircle(pos, 100));
  11.  
  12.     try
  13.     {
  14.         _monitor.Geofences.Add(fence);
  15.     }
  16.     catch (Exception)
  17.     {
  18.         //geofence already added to system
  19.     }
  20. }

First we hook up the GeofenceStateChanged event, we’ll look at the eventhandler in a minute. Then we create a BasicGeoPosition which holds the coordinates for, in our case, building 9 of the Microsoft campus in Redmond. Then we create a Geofence. The Geofence constructor takes two parameters, a string that functions as ID so it should be unique, and an IGeoShape. Other overloads for Geofence allow us to specify if we want to trigger the event whenever we enter or leave the geofence area.

For the ID we use a string, for the IGeoShape we use a GeoCircle. Other build-in possibilities are

  • Geoboundingbox
  • Geocircle
  • Geopath
  • Geopoint

The Geocircle takes two parameters, the position and the radius (in meters). We’ve already defined a position as BasicGeoposition, which is exactly the type expected by the Geocircle, and we define a radius of 100 meters. Finally we try to add the Geofence to the geofences registered in the OS. If a Geofence with the same ID already exists it will throw an exception stating that the object already exists.

Let’s have a look at the event handler

Code Snippet
  1. private void MonitorOnGeofenceStateChanged(GeofenceMonitor sender, object args)
  2. {
  3.     var fences = sender.ReadReports();
  4.  
  5.     foreach (var report in fences)
  6.     {
  7.         if (report.Geofence.Id != "building9")
  8.             continue;
  9.  
  10.         switch (report.NewState)
  11.         {
  12.             case GeofenceState.Entered:
  13.                 Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
  14.                 {
  15.                     MessageDialog dialog = new MessageDialog("Welcome to building 9");
  16.  
  17.                     await dialog.ShowAsync();
  18.                 });
  19.                 break;
  20.             case GeofenceState.Exited:
  21.                 Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
  22.                 {
  23.                     MessageDialog dialog = new MessageDialog("Leaving building 9");
  24.  
  25.                     await dialog.ShowAsync();
  26.                 });
  27.                 break;
  28.         }
  29.     }
  30. }

Before we can show a message we’ll need to know what geofence triggered the event. We do that by calling ReadReports on the GeofenceMonitor. This method will return a ReadOnlyList containing GeofenceStateChangedReports. Iterating over those reports we can check the ID of the geofence and take action when the expected geofence is triggered. In this case we want to show a welcome message when someone arrives and a leaving message when someone leaves. Let’s try it out!

Launch the app in the emulator (unless you’re physically at building 9, then you can use a WP8.1 device Glimlach), open the emulator tools and set the location to building 9. You’ll have to wait some seconds before the message pops up, this is to prevent triggers being fired when just passing through a geofence location. You can manipulate this delay by using an overload of the Geofence constructor and setting the DwellTime parameter (TimeSpan).

Clear your location and set it somewhere away from building 9, wait a few seconds and watch the leaving message.

Conclusion

Geofencing is a pretty cool way to interact with users based on their location. It’s a great addition to the platform and personally I can’t wait to see what great ideas devs will come up with to use this functionality.

In this post I did a quick, basic lap around geofencing. Geofences can also trigger a backgroundtask, provided the app is set as lockscreen app, so the app doesn’t need to run all the time for geofencing to do its stuff.

As usual, the code can be found on my OneDrive


Tags:

WinRT | WP8 | geofencing

Building a REST API and consuming it in WP8

by Nico

As a mobile developer we often need to consume some API in order to get data. In a lot of cases that API is made available to us by some third party, for example Twitter, Facebook, Flickr, ...  However, in some cases we are ourselves responsible for the data. In order to get the data from our datastore to our app we’ll need to build an API. In this article I’ll walk you through creating a basic API with the CRUD operations and consume it in a Windows Phone app.

For this post I’ll be using

  • ASP.NET WebApi 2.1
  • Visual Studio 2013
  • Microsoft Azure Websites
  • Windows Phone

The API will be build in WebApi 2.1 and hosted on Azure Websites. I’ve chosen Azure Websites because they offer 10 free websites and have great integration in Visual Studio 2013 update 1. Feel free to choose any other webhost, as long as they support MVC 5 you should be fine.

Setting up the API project

All right, let’s get started by building the API. In Visual Studio 2013 select File > New Project > Web > ASP.NET Web Application. In the next window, select Web API. If you’re deploying to Azure, check the “Create remote resources” box. This will create either an Azure Website or an Azure Virtual Machine for you. We’re not doing any authentication for this post, I’m saving that for a future post Glimlach, so leave it at No Authentication and click OK.

Visual Studio will create your project, tell Azure to create a Website and setup publish profiles for you. If you run this project you’ll get an ASP.NET MVC application with the default template but underneath it has also fired up a WebAPI. If you click the API link in the default template it will show you all available API calls (the WebApi template has a demo controller to get you started).

Now, for our API we’re going to create a database that holds famous quotes. Nothing fancy, just a database with one table that holds quotes. This is the Quote class

Code Snippet
  1. public class Quotes
  2. {
  3.     public int ID { get; set; }
  4.     public string Quote { get; set; }
  5. }

Time to add our API controller. If you’re familiar with MVC then this will look very familiar. WebAPI is basically MVC without the V. You have Models, you have controllers but instead of returning a view, the controllers return a Rest result, by default in JSON.

Right-click the controllers folder > Add > Controller. Select “Web API 2 controller with actions, using Entity Framework”. In the Model class dropdown select the Quotes class we’ve just created. The Data context drop down is where we can select our Entity framework context but that hasn’t been created yet. Click the + button next to the dropdown, select a name and click Add. Now we do have a context. Click Add and let Visual Studio create your Controller for you.

The newly created controller features all CRUD operations using the context we’ve just created to get to our Entity Framework. Before testing this, have a look in the Web.config file. You should find something like this not far from the top of the file

Code Snippet
  1. <connectionStrings>
  2.   <add name="RestDemoContext" connectionString="Data Source=(localdb)\v11.0; Initial Catalog=RestDemoContext-20140327114532; Integrated Security=True; MultipleActiveResultSets=True; AttachDbFilename=|DataDirectory|RestDemoContext-20140327114532.mdf"
  3.     providerName="System.Data.SqlClient" />
  4. </connectionStrings>

This is the database connection that Entity Framework will use. It’s currently set to a local SQL Express database but a SQL Azure database has been created together with our project when we were first setting it up, so we’ll need to change this. Login to the Azure portal and go to Databases, find the created database for your project and select  “View SQL Database connection strings for ADO .Net, ODBC, PHP, and JDBC”.

Copy the ADO.NET connectionstring and paste it into the Web.config so that the line from before now looks like this

Code Snippet
  1. <connectionStrings>
  2.   <add name="RestDemoContext" connectionString="Server=tcp:tvez9dpih8.database.windows.net,1433;Database=RestDemo_db;User ID={Your_userID_here};Password={your_password_here};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;"
  3.     providerName="System.Data.SqlClient" />
  4. </connectionStrings>

Don’t forget to fill in your correct user ID and password. If you’ve set everything up, it’s time to try this out. Launch the project and navigate to the API link from the page header. It should now show you all available actions from your new controller. Click on the POST entry from the Quotes controller. This page shows you how a body from a POST request to this controller should look like. Let’s try it out in Fiddler.

Open Fiddler while your project is still running and go to the Composer tab. Set the method to POST from the dropdown and enter the url to your API endpoint. In my case this was http://localhost:36264/api/quotes. In the request headers field add this line

Content-Type: application/json

This will tell our API that the body contains JSON formatted data. In the request body we can copy/paste the sample data that the API page from the project gave us and fill in some nice quote.

{
  "ID": 1,
  "Quote": "you have failed me for the last time"
}

Click Execute and after a few seconds Fiddler should show a 201 result. HTTP code 201 means “Created” so our post was successful. Change the method to GET, clear the body and click execute again. Fiddler should show a 200. Select that line and the Inspectors Tab to see the result.

 

A closer look

Let’s take a closer look at the API methods.

Code Snippet
  1. // GET: api/Quotes/5
  2. [ResponseType(typeof(Quotes))]
  3. public async Task<IHttpActionResult> GetQuotes(int id)
  4. {
  5.     Quotes quotes = await db.Quotes.FindAsync(id);
  6.     if (quotes == null)
  7.     {
  8.         return NotFound();
  9.     }
  10.  
  11.     return Ok(quotes);
  12. }

The first line is a comment (obviously Glimlach) that shows you how to call this method. The second line is an attribute to specify the expected content type in the response. Skip ahead to lines 8 and 11. These are helper methods found in the ApiController base class. When called they create a response with the correct HTTP code, 404 for not found or 200 for ok in this case, and set the content of the response.

We could add a second attribute to this method called HttpGet. Each of the verbs (GET, PUT, POST, DELETE) have an attribute version. You can use them freely here but the default template is working with a convention. Every method where the name starts with Get will be a GET method by default, the same for PUT, POST and DELETE.

Publish to Azure Websites

Publishing to your Azure website is as easy as right-clicking your web project (NOT the solution) and selecting publish. Let Visual Studio do its thing, your browser will open and your API is live on the internet. We can even debug live on the azure website by opening Server Explorer in Visual Studio > Azure > Websites > right-click your site > Attach Debugger (note that this works best when you deployed a debug build of your site.

Creating the app

Time to consume our fancy API. Create a new blank Windows Phone 8 application and add the following Nuget packages

  • Install-Package Microsoft.Net.Http
  • Install-Package Newtonsoft.Json
  • Install-Package MvvmLight

So what are these for? The first one gives us the HttpClient class which is a far superior way to do HTTP requests in Windows Phone than any class included in the SDK. It’s also a portable library so it makes your code very easy to port over to other platforms. Json.net because we’ll receive a JSON response from our API and we need to deserialize it back to an object. And MVVM Light because I just can’t live without it.

Getting data

We’ll start by requesting all quotes currently in the database. First, add the Quotes class from the API project to the phone project. Second, add a LongListSelector to the MainPage

Code Snippet
  1. <phone:LongListSelector ItemsSource="{Binding Quotes}">
  2.     <phone:LongListSelector.ItemTemplate>
  3.         <DataTemplate>
  4.             <TextBlock Style="{StaticResource PhoneTextNormalStyle}" Text="{Binding Quote}" />
  5.         </DataTemplate>
  6.     </phone:LongListSelector.ItemTemplate>
  7. </phone:LongListSelector>

Next, in the MainViewModel we’ll fetch the data and set it to Quotes (don’t forget to set MainViewModel as datacontext of MainPage).

Code Snippet
  1. private ObservableCollection<Quotes> _quotes;
  2.  
  3. public ObservableCollection<Quotes> Quotes
  4. {
  5.     get { return _quotes; }
  6.     set
  7.     {
  8.         if (_quotes == value) return;
  9.  
  10.         _quotes = value;
  11.         RaisePropertyChanged(() => Quotes);
  12.     }
  13. }
  14.  
  15. /// <summary>
  16. /// Initializes a new instance of the MainViewModel class.
  17. /// </summary>
  18. public MainViewModel()
  19. {
  20.     FetchQuotes();
  21. }
  22.  
  23. private async Task FetchQuotes()
  24. {
  25.     using (HttpClient client = new HttpClient())
  26.     {
  27.         var result = await client.GetAsync("http://restdemo.azurewebsites.net/api/quotes");
  28.  
  29.         result.EnsureSuccessStatusCode();
  30.  
  31.         Quotes = new ObservableCollection<Quotes>(JsonConvert.DeserializeObject<IEnumerable<Quotes>>(await result.Content.ReadAsStringAsync()));
  32.     }
  33. }

Quotes is an ObservableCollection of type Quotes. FetchQuotes does all the heavy lifting here and is called upon initialization of the MainViewModel. It creates an instance of HttpClient (in a using statement, because HttpClient implements IDisposable). It calls our API endpoint that returns all quotes from the database. When it’s done fetching data we call EnsureSuccessStatusCode on the result. This method will throw an error if the returned HTTP code is not a success code, for example when we should receive a not found or bad request error. If everything went well we can read the result.Content as a string, this will give us the quotes in a JSON string format. We feed it into JSON.net his deserializer and we’re done!

Now what good is having our own API when all we do is reading from it? Time to post some quotes! Add a second page and a way to navigate to that page. To keep things simple I’ve hooked this AddPage up to MainViewModel as datacontext. So I have 2 pages and 1 viewmodel. In the Viewmodel I create a new property that will hold the new quote.

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

The page contains a textbox that has a two-way binding to this property

Code Snippet
  1. <StackPanel x:Name="ContentPanel"
  2.             Grid.Row="1"
  3.             Margin="12,0,12,0">
  4.     <TextBlock Style="{StaticResource PhoneTextNormalStyle}" Text="Quote" />
  5.     <TextBox Text="{Binding NewQuote.Quote, Mode=TwoWay}" />
  6. </StackPanel>

And to glue things together, there’s a save method in the Viewmodel that will POST this new quote to the API, clear the NewQuote property and refetch all properties, including the one we just saved.

Code Snippet
  1. public async Task SaveQuote()
  2. {
  3.     using (HttpClient client = new HttpClient())
  4.     {
  5.         HttpContent content = new StringContent(JsonConvert.SerializeObject(NewQuote));
  6.         content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  7.  
  8.         var result = await client.PostAsync("http://restdemo.azurewebsites.net/api/quotes", content);
  9.  
  10.         result.EnsureSuccessStatusCode();
  11.     }
  12.  
  13.     NewQuote = new Quotes();
  14.     await FetchQuotes();
  15. }

To do a POST we first need to prepare the content. In our case we’re going to send a JSON string so we need to convert our NewQuote into JSON and put it inside StringContent. Next step is setting the ContentType in the header, just like we did when using Fiddler a few steps ago. Call PostAsync on the HttpClient, ensure its success and we’re done. If all went well the api saved the quote, the app refetched all quotes and the new one should show up on the MainPage.

Conclusion

In this article I’ve shown the steps needed to build and consume a basic REST API using ASP.net WebApi and Windows Phone 8. The code from the WP8 app is very generic and can be used on a lot of platforms, even for platforms where HttpClient isn’t available, the way of working, the headers, the expected HTTP codes, should all be the same.

The code for both the API and the app can be found on my OneDrive.


Tags:

.Net | Azure | Data | WP8 | WinRT | REST

WP8 as bluetooth Start button

by Nico

If you’ve ever used applications like the Office Remote that seem to take over your computer you’ll know that it can provide quite the “magic” experience. As with all magic technologies this one is quite simple as well. All we need is a computer with Bluetooth that runs a small app with a Bluetooth listener and a Windows Phone app that connects to that listener app via Bluetooth. For this demo app I’m going to make the Windows Phone app act like the Start button on a Windows machine.

Simulating the Windows key

The listener application is a small WPF app that has only one button. That button will act like the Start button. To interact with the operating system and simulate a keyboard press we’ll need to import user32.dll and hook into its keybd_event. We’ll want to send ctrl + esc to Windows (acts the same as the Windows key)

Code Snippet
  1. //source: http://www.codeproject.com/Questions/46731/Open-Start-Menu
  2. private static void ShowStartMenu()
  3. {
  4.     // key down event:
  5.     const byte keyControl = 0x11;
  6.     const byte keyEscape = 0x1B;
  7.     keybd_event(keyControl, 0, 0, UIntPtr.Zero);
  8.     keybd_event(keyEscape, 0, 0, UIntPtr.Zero);
  9.  
  10.     // key up event:
  11.     const uint keyeventfKeyup = 0x02;
  12.     keybd_event(keyControl, 0, keyeventfKeyup, UIntPtr.Zero);
  13.     keybd_event(keyEscape, 0, keyeventfKeyup, UIntPtr.Zero);
  14. }
  15.  
  16. [DllImport("user32.dll")]
  17. static extern void keybd_event(byte bVk, byte bScan, uint dwFlags,
  18.    UIntPtr dwExtraInfo);

In the event handler of the button we call ShowStartMenu() and behold: a wild software Windows key appears!

Building the Bluetooth listener

Adding Bluetooth support to a .NET application isn’t the easiest thing to do. Luckily for us there are libraries out there that take out the hassle. For this project I used Peter Foot’s 32feet.NET library available through NuGet

Install-Package 32feet.NET

A small note on this package as found on the 32feet.NET product page

“Bluetooth support requires a device with the Microsoft or Widcomm Bluetooth stack”

Luckily for me, my device uses the Microsoft BT stack, so I’m good to go. Now on to the code, we’ll need to start a BT listener and once connected read data from a networkstream. If we receive a certain message we’ll execute the ShowStartMenu() method.

First some fields

Code Snippet
  1. private BluetoothListener _listener;
  2.  
  3. //unique service identifier
  4. private readonly Guid _service = new Guid("{7A51FDC2-FDDF-4c9b-AFFC-98BCD91BF93B}");
  5. private bool _connected;

BluetoothListener is a class we get from 32feet.NET. The GUID is a reference to the service this app is providing, our Windows Phone app will need the same GUID to be able to connect to this service. And the third field is a boolean to keep track of having a connected client or not.

Code Snippet
  1. private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
  2. {
  3.     BluetoothRadio br = BluetoothRadio.PrimaryRadio;
  4.  
  5.     if (br == null)
  6.     {
  7.         MessageBox.Show("No supported Bluetooth radio/stack found.");
  8.     }
  9.     else if (br.Mode != RadioMode.Discoverable)
  10.     {
  11.         MessageBoxResult rslt = MessageBox.Show("Make BluetoothRadio Discoverable?",
  12.             "Bluetooth Remote Listener", MessageBoxButton.YesNo);
  13.  
  14.         if (rslt == MessageBoxResult.Yes)
  15.         {
  16.             br.Mode = RadioMode.Discoverable;
  17.         }
  18.     }
  19.  
  20.     _listener = new BluetoothListener(_service);
  21.     _listener.Start();
  22.  
  23.     System.Threading.Thread t = new System.Threading.Thread(ListenLoop);
  24.     t.Start();
  25. }

In the OnLoaded event from the MainWindow we’ll first check if there’s a BT radio found that works on the MS or Widcomm stack. If that’s found, and made discoverable, we’ll start the listener with the service GUID specified in the field. Once the listener is started we fire up a second thread that will contain a loop to connect a client and read data from the stream.

Code Snippet
  1. private void ListenLoop()
  2. {
  3.     byte[] buffer = new byte[1024];
  4.  
  5.     while (true)
  6.     {
  7.         BluetoothClient bc;
  8.         Stream ns;
  9.  
  10.         try
  11.         {
  12.             bc = _listener.AcceptBluetoothClient();
  13.             ns = bc.GetStream();
  14.             _connected = true;
  15.         }
  16.         catch
  17.         {
  18.             break;
  19.         }
  20.  
  21.         //keep connection open
  22.         while (_connected)
  23.         {
  24.             try
  25.             {
  26.                 int received = ns.Read(buffer, 0, buffer.Length);
  27.  
  28.                 if (received > 0)
  29.                 {
  30.                     string data = Encoding.UTF8.GetString(buffer);
  31.  
  32.                     string command = data.Substring(0, data.IndexOf("\0", StringComparison.Ordinal));
  33.  
  34.                     if (command == "Start")
  35.                     {
  36.                         ShowStartMenu();
  37.                     }
  38.                 }
  39.                 else
  40.                 {
  41.                     //connection lost
  42.                     _connected = false;
  43.                 }
  44.             }
  45.             catch
  46.             {
  47.                 _connected = false;
  48.                 break;
  49.             }
  50.         }
  51.  
  52.         try
  53.         {
  54.             bc.Close();
  55.         }
  56.         catch
  57.         {
  58.         }
  59.     }
  60. }

This is the code for the loop that runs in the second thread. First we declare a buffer of 1KB, more than enough for this sample. Next we start an infinite loop, in that loop we declare a BluetoothClient and a Stream. Once a client connects through the AcceptBluetoothClient method we fetch a stream and set the connected flag to true. As long as we’re connected we read data from the stream into the buffer, once we receive actual data we’ll decode it from a byte array (the buffer) into a string (the original message). In this sample the message will be 5 bytes but the buffer can hold 1024 bytes. It will fill up the remaining bytes with “\0” so we’ll need to chop that of with a Substring. If the received string is “Start” we’ll flip to the Start screen. If we read from the stream but the number of received bytes is zero, we’ve lost the connection to the client.

Fire up the WPF app, make sure the button flips you to the Start screen and let’s get started on the WP8 app!

Windows Phone Client

The Windows Phone app consists of two pages. The MainPage is for selecting a Bluetooth peer to connect to and the ConnectedPage has the same button as the WPF application. The app uses MVVM Light, everything happens in the MainViewModel. Both the MainPage and ConnectedPage use MainViewModel as their datacontext. For navigation I’ve added the always helpful Cimbalino NuGet package and registered their NavigationService in SimpleIoc through the ViewModelLocator

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.     }
  9.     else
  10.     {
  11.         // Create run time view services and models
  12.         SimpleIoc.Default.Register<INavigationService, NavigationService>();
  13.     }
  14.  
  15.     SimpleIoc.Default.Register<MainViewModel>();
  16. }

In the MainViewModel I have declared three properties

Code Snippet
  1. private ObservableCollection<PeerInformation> _peers;
  2. private PeerInformation _selectedPeer;
  3. private ICommand _goToStartCommand;
  4.  
  5. public ICommand GoToStartCommand
  6. {
  7.     get { return _goToStartCommand ?? (_goToStartCommand = new RelayCommand(SendCommand)); }
  8. }
  9.  
  10. public ObservableCollection<PeerInformation> Peers
  11. {
  12.     get { return _peers; }
  13.     set
  14.     {
  15.         if (_peers == value) return;
  16.  
  17.         _peers = value;
  18.         RaisePropertyChanged(() => Peers);
  19.     }
  20. }
  21.  
  22. public PeerInformation SelectedPeer
  23. {
  24.     get { return _selectedPeer; }
  25.     set
  26.     {
  27.         if (_selectedPeer == value) return;
  28.  
  29.         _selectedPeer = value;
  30.         RaisePropertyChanged(() => SelectedPeer);
  31.  
  32.         ConnectToDevice();
  33.     }
  34. }

The PeerInformation class is something we get from the Windows Phone Bluetooth API. We have an observablecollection that will hold all peers that are known for your Windows Phone device, we also have a property for the selected peer and a command that will fire a message into the NetworkStream.

We’ll also need some fields

Code Snippet
  1. private StreamSocket _socket;
  2. private DataWriter _dataWriter;
  3.  
  4. private readonly INavigationService _navigationService;

The socket will hold the connection between the phone app and the WPF app. The DataWriter can write data into the stream. The NavigationService is the one from the Cimbalino toolkit.

Here’s the constructor for the MainViewModel

Code Snippet
  1. public MainViewModel(INavigationService navigationService)
  2. {
  3.     if (IsInDesignModeStatic) return;
  4.  
  5.     _navigationService = navigationService;
  6.  
  7.     if (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Emulator)
  8.     {
  9.         MessageBox.Show("Bluetooth not available in the emulator");
  10.     }
  11.     else
  12.     {
  13.         RefreshPairedDevicesList();
  14.     }
  15. }

The NavigationService is injected via SimpleIoc. First we check if the current device is the Windows Phone emulator, the emulator doesn’t support Bluetooth so we need an actual device to test this on.

The RefreshPairedDevicesList looks like this (all using the Windows Phone Bluetooth APIs)

Code Snippet
  1. private async void RefreshPairedDevicesList()
  2. {
  3.     try
  4.     {
  5.         // Search for all paired devices
  6.         PeerFinder.AlternateIdentities["Bluetooth:Paired"] = "";
  7.         var peers = await PeerFinder.FindAllPeersAsync();
  8.  
  9.         Peers = new ObservableCollection<PeerInformation>(peers);
  10.     }
  11.     catch (Exception ex)
  12.     {
  13.         if ((uint)ex.HResult == 0x8007048F)
  14.         {
  15.             if (MessageBox.Show("Bluetooth is off, enable it?",
  16.                 "Bluetooth Off", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
  17.             {
  18.                 ConnectionSettingsTask connectionSettingsTask = new ConnectionSettingsTask
  19.                 {
  20.                     ConnectionSettingsType = ConnectionSettingsType.Bluetooth
  21.                 };
  22.                 connectionSettingsTask.Show();
  23.                 RefreshPairedDevicesList();
  24.             }
  25.         }
  26.         else
  27.         {
  28.             MessageBox.Show(ex.Message);
  29.         }
  30.     }
  31. }

First we’ll look for all paired devices for our phone, those get pushed into the observablecollection. If that fails with result 0x8007048F that means that Bluetooth is disabled on the device, in that case we use the ConnectionSettingsTask to redirect the user to the Bluetooth settings page in WP8.

After the list of peers is build, the user will be able to select one (I’ll discuss the pages in a minute). When a peer is selected we open up the Bluetooth connection

Code Snippet
  1. private async void ConnectToDevice()
  2. {
  3.     if (_socket != null)
  4.     {
  5.         // Disposing the socket with close it and release all resources associated with the socket
  6.         _socket.Dispose();
  7.     }
  8.  
  9.     try
  10.     {
  11.         _socket = new StreamSocket();
  12.  
  13.         //connect to the service with specified GUID
  14.         await _socket.ConnectAsync(SelectedPeer.HostName, "{7A51FDC2-FDDF-4c9b-AFFC-98BCD91BF93B}");
  15.  
  16.         // Connection was successful
  17.         _dataWriter = new DataWriter(_socket.OutputStream);
  18.         _navigationService.NavigateTo("/ConnectedPage.xaml");
  19.     }
  20.     catch (Exception ex)
  21.     {
  22.         MessageBox.Show(ex.Message);
  23.  
  24.         _socket.Dispose();
  25.         _socket = null;
  26.     }
  27. }

The ConnectAsync method takes in the hostname of the peer and the same GUID we used in the WPF application to start the service. Once the connection is made we take the OutputStream and use it to initialize the DataWriter and we navigate to the ConnectedPage.

Let’s have a quick look at the MainPage xaml.

Code Snippet
  1. <phone:LongListSelector ItemsSource="{Binding Peers}">
  2.     <phone:LongListSelector.ItemTemplate>
  3.         <DataTemplate>
  4.             <TextBlock Margin="12, 0, 0, 12"
  5.                        Style="{StaticResource PhoneTextTitle2Style}"
  6.                        Text="{Binding DisplayName}" />
  7.         </DataTemplate>
  8.     </phone:LongListSelector.ItemTemplate>
  9.     <i:Interaction.Behaviors>
  10.         <behaviors:SelectedItemBehavior SelectedItem="{Binding SelectedPeer, Mode=TwoWay}" />
  11.     </i:Interaction.Behaviors>
  12.  
  13. </phone:LongListSelector>

The MainPage consists of a LongListSelector with an ItemsSource bound to the observableCollection on the MainViewModel. as a DataContext we show the displaynames of all available peers.

NOTE: LongListSelector does not support SelectedItem binding. I’ve added a behavior to this project that gives us just that. For more information on the behavior see my blogpost from a while ago.

The ConnectedPage only has a button with a command bound to the GoToStartCommand on MainViewModel. Once that command is fired we send a string “Start” on to the stream.

Code Snippet
  1. private async void SendCommand()
  2. {
  3.     _dataWriter.WriteString("Start");
  4.     await _dataWriter.StoreAsync();
  5.     await _dataWriter.FlushAsync();
  6. }

And that’s it! The message gets written into the DataWriter, stored in the stream and the stream gets flushed. In the WPF app the string gets read into the buffer as a byte array, gets converted back into a string and the Start screen appears!

Wrap-up

In this post I’ve discussed how to connect your Windows Phone device to another bluetooth enabled device and use a service running there.

Happy coding!


Tags:

.Net | Devices | Bluetooth | MVVM Light | WP8 | WPF | XAML | Windows programming

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

LLS SelectedItem binding through a behavior

by Nico

Back in August I blogged about the ExtendedSelector, an extension of the LongListSelector that gave us a bindable SelectedItem property. A bit of a downside of this approach is that it’s basically a new control. Sure it inherits from the classic LLS underneath but it’s still another control in your XAML code.

Well, to fix this I’ve recreated the SelectedItem dependency property  through a behavior.

The behavior

Code Snippet
  1. public class SelectedItemBehavior : Behavior<LongListSelector>
  2. {
  3.     public readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(
  4.         "SelectedItem", typeof(object), typeof(SelectedItemBehavior), new PropertyMetadata(default(object)));
  5.  
  6.     public object SelectedItem
  7.     {
  8.         get { return GetValue(SelectedItemProperty); }
  9.         set { SetValue(SelectedItemProperty, value); }
  10.     }
  11.  
  12.     protected override void OnAttached()
  13.     {
  14.         AssociatedObject.SelectionChanged += AssociatedObjectOnSelectionChanged;
  15.  
  16.         base.OnAttached();
  17.     }
  18.  
  19.     protected override void OnDetaching()
  20.     {
  21.         AssociatedObject.SelectionChanged -= AssociatedObjectOnSelectionChanged;
  22.  
  23.         base.OnDetaching();
  24.     }
  25.  
  26.     private void AssociatedObjectOnSelectionChanged(object sender, SelectionChangedEventArgs args)
  27.     {
  28.         SelectedItem = args.AddedItems[0];
  29.     }
  30. }

It’s an easy one really. The behavior inherits from Behavior<LongListSelector> and has one dependency property. When the behavior gets attached to an LLS we attach the event handler to the SelectionChanged event. When detaching we cleanup by detaching the event handler.

When the SelectionChanged event fires we push the selected item into the dependency property.

Usage

Let’s throw together a quick little app to show the usage of the behavior. First the infamous Person class

Code Snippet
  1. public class Person
  2. {
  3.     public string Name { get; set; }
  4.     public int Age { get; set; }
  5. }

Next is the MainViewModel

Code Snippet
  1. public class MainViewModel : INotifyPropertyChanged
  2. {
  3.     private ObservableCollection<Person> _persons;
  4.     private Person _selectedPerson;
  5.  
  6.     public ObservableCollection<Person> Persons
  7.     {
  8.         get { return _persons; }
  9.         set
  10.         {
  11.             if (_persons == value) return;
  12.  
  13.             _persons = value;
  14.  
  15.             OnPropertyChanged();
  16.         }
  17.     }
  18.  
  19.     public Person SelectedPerson
  20.     {
  21.         get { return _selectedPerson; }
  22.         set
  23.         {
  24.             if (_selectedPerson == value) return;
  25.  
  26.             _selectedPerson = value;
  27.  
  28.             OnPropertyChanged();
  29.         }
  30.     }
  31.  
  32.     public MainViewModel()
  33.     {
  34.         Persons = new ObservableCollection<Person>();
  35.         Random rnd = new Random();
  36.  
  37.         for (int i = 0; i < 20; i++)
  38.         {
  39.             var person = new Person {Name = "Person " + i, Age = rnd.Next(0, 80)};
  40.  
  41.             Persons.Add(person);
  42.         }
  43.     }
  44.  
  45.     public event PropertyChangedEventHandler PropertyChanged;
  46.  
  47.     protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  48.     {
  49.         PropertyChangedEventHandler handler = PropertyChanged;
  50.         if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
  51.     }
  52. }

Two properties here, an observable collection that holds the persons and a SelectedPerson that will be bound to the dependency property on our behavior. The list of persons gets filled with some random data from the constructor.

Here’s the view

Code Snippet
  1. <Grid x:Name="LayoutRoot" Background="Transparent">
  2.     <Grid.RowDefinitions>
  3.         <RowDefinition Height="Auto" />
  4.         <RowDefinition Height="*" />
  5.     </Grid.RowDefinitions>
  6.  
  7.     <!--  TitlePanel contains the name of the application and page title  -->
  8.     <StackPanel x:Name="TitlePanel"
  9.         Grid.Row="0"
  10.         Margin="12,17,0,28">
  11.         <TextBlock Margin="12,0"
  12.             Style="{StaticResource PhoneTextNormalStyle}"
  13.             Text="MY APPLICATION" />
  14.         <TextBlock Margin="9,-7,0,0"
  15.             Style="{StaticResource PhoneTextTitle1Style}"
  16.             Text="page name" />
  17.     </StackPanel>
  18.  
  19.     <!--  ContentPanel - place additional content here  -->
  20.     <Grid x:Name="ContentPanel"
  21.         Grid.Row="1"
  22.         Margin="12,0,12,0">
  23.  
  24.         <Grid.RowDefinitions>
  25.             <RowDefinition Height="Auto" />
  26.             <RowDefinition Height="*" />
  27.         </Grid.RowDefinitions>
  28.         <TextBlock Grid.Row="0">
  29.             <Run Text="Selected person is " />
  30.             <Run Text="{Binding SelectedPerson.Age}" />
  31.             <Run Text=" years old" />
  32.         </TextBlock>
  33.         <phone:LongListSelector Grid.Row="1"
  34.             ItemsSource="{Binding Persons}">
  35.             <phone:LongListSelector.ItemTemplate>
  36.                 <DataTemplate>
  37.                     <Grid Margin="0, 12, 0, 0">
  38.                         <TextBlock Text="{Binding Name}" />
  39.                     </Grid>
  40.                 </DataTemplate>
  41.             </phone:LongListSelector.ItemTemplate>
  42.             <i:Interaction.Behaviors>
  43.                 <vm:SelectedItemBehavior SelectedItem="{Binding SelectedPerson, Mode=TwoWay}"/>
  44.             </i:Interaction.Behaviors>
  45.         </phone:LongListSelector>
  46.     </Grid>
  47. </Grid>

Let’s extract the LongListSelector from that page as that’s the important piece

Code Snippet
  1. <phone:LongListSelector Grid.Row="1"
  2.     ItemsSource="{Binding Persons}">
  3.     <phone:LongListSelector.ItemTemplate>
  4.         <DataTemplate>
  5.             <Grid Margin="0, 12, 0, 0">
  6.                 <TextBlock Text="{Binding Name}" />
  7.             </Grid>
  8.         </DataTemplate>
  9.     </phone:LongListSelector.ItemTemplate>
  10.     <i:Interaction.Behaviors>
  11.         <vm:SelectedItemBehavior SelectedItem="{Binding SelectedPerson, Mode=TwoWay}"/>
  12.     </i:Interaction.Behaviors>
  13. </phone:LongListSelector>

The ItemsSource is bound to the Persons ObservableCollection on the viewmodel. Underneath the ItemTemplate we attach the behavior and bind its property to the SelectedItem.

And that’s it, every time a person is selected from the LLS the SelectedPerson property gets updated on the viewmodel.


Tags:

.Net | Devices | WP8 | XAML | Binding

  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