Nico's digital footprint

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

Extending the Windows Phone pivot

by Nico

As I was working on a Windows Phone 8 project I needed a pivot that could hide its title, giving back some screen real-estate when needed. The basic pivot that is included in the Windows Phone SDK doesn’t have this kind of behavior so it was a great opportunity to try out custom controls in Windows Phone. I’ve build custom controls in XAML before but never based on an existing one, so fun times ahead. Let me start by showing a side-by-side comparison between both views of my pivot.

don’t mind the overlapping textblock and button, point is that when the button is clicked, the title of the pivot disappears.

Building a XAML custom control

It’s quite easy to build a custom control in XAML as long as you follow the guidelines. It requires you to add a folder called Themes and in the folder a file called generic.xaml. The generic.xaml file is a resource dictionary, no code behind file is needed. Do follow the naming conventions exactly or your control won’t work. Next step is adding a class that inherits from ContentControl (or a control that already inherits from ContentControl). The project for my ExtendedPivot looks like this

The project type is a WP8 class library containing two custom controls, one for the pivot and one for the pivot items.

Extending the pivot

Since I only want to add a functionality to an existing control, the Pivot, my ExtendedPivot class inherits from Pivot instead of CustomControl.

Code Snippet
  1. publicclassExtendedPivot : Pivot
  2. {
  3.     publicstaticreadonlyDependencyProperty HeaderVisibilityProperty =
  4.         DependencyProperty.Register("HeaderVisibilityProperty", typeof (Visibility), typeof (ExtendedPivot), newPropertyMetadata(null));
  5.  
  6.     publicVisibility HeaderVisibility
  7.     {
  8.         get { return (Visibility)GetValue(HeaderVisibilityProperty); }
  9.         set { SetValue(HeaderVisibilityProperty, value); }
  10.     }
  11.  
  12.     public ExtendedPivot()
  13.     {
  14.         DefaultStyleKey =  typeof(ExtendedPivot);
  15.     }
  16. }

We’ll start with the constructor, Line 14 is necessary when developing a custom control, it sets the style of the control to the style defined in generic.xaml (we’ll get to that style in a minute). Lines 6 – 10 are a property that will be used by the DependencyProperty. The DependencyProperty (lines 3-4) is a property that we can bind a value to when using the control in a project, it might seem a bit overwhelming at first but there’s a great snippet in VS2012 to easily write them. Basically, the parameters for the Register function are a name, the type of the property, the owner type (type of the control where you’re declaring the DP) and some metadata.

The get and set method of the normal property use the DP to get and set values through databinding.

generic.xaml

This is the style for the ExtendedPivot as declared in generic.xaml

Code Snippet
  1. <Style TargetType="local:ExtendedPivot">
  2.     <Setter Property="Margin" Value="0" />
  3.     <Setter Property="Padding" Value="0" />
  4.     <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}" />
  5.     <Setter Property="Background" Value="Transparent" />
  6.     <Setter Property="ItemsPanel">
  7.         <Setter.Value>
  8.             <ItemsPanelTemplate>
  9.                 <Grid />
  10.             </ItemsPanelTemplate>
  11.         </Setter.Value>
  12.     </Setter>
  13.     <Setter Property="Template">
  14.         <Setter.Value>
  15.             <ControlTemplate TargetType="local:ExtendedPivot">
  16.                 <Grid HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
  17.                     <Grid.RowDefinitions>
  18.                         <RowDefinition Height="Auto" />
  19.                         <RowDefinition Height="Auto" />
  20.                         <RowDefinition Height="*" />
  21.                     </Grid.RowDefinitions>
  22.                     <Grid Grid.RowSpan="3" Background="{TemplateBinding Background}" />
  23.                     <ContentControl Grid.Row="0"
  24.                                     Margin="24,17,0,-7"
  25.                                     HorizontalAlignment="Left"
  26.                                     Content="{TemplateBinding Title}"
  27.                                     ContentTemplate="{TemplateBinding TitleTemplate}"
  28.                                     Visibility="{TemplateBinding HeaderVisibility}" />
  29.                     <primitives:PivotHeadersControl x:Name="HeadersListElement" Grid.Row="1" />
  30.                     <ItemsPresenter x:Name="PivotItemPresenter"
  31.                                     Grid.Row="2"
  32.                                     Margin="{TemplateBinding Padding}" />
  33.                 </Grid>
  34.             </ControlTemplate>
  35.         </Setter.Value>
  36.     </Setter>
  37. </Style>

Basically, I’ve created a xaml page in some very basic Windows Phone project, right-clicked it, selected Edit Template > Edit a copy. This gives you a copy of the template for the Pivot. I copied that template in the generic.xaml style. The ContentControl at Lines 23-28 show the title in the pivot. I added the Visiblity property here and bound it to the HeaderVisibility property in the ExtendedPivot class. To bind a property in a style you need to use the TemplateBinding keyword instead of the normal Binding one.

Don’t forget to set TargetType to the type of your custom control.

Using the custom control in an app

The control is ready, now it’s time to use it. Create a new Windows Phone app and reference the project or DLL of the custom control. This is the MainPage of the sample app.

Code Snippet
  1. <phone:PhoneApplicationPage x:Class="ExtendedPivot.MainPage"
  2.                             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.                             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.                             xmlns:control="clr-namespace:ExtendedPivot.Control;assembly=ExtendedPivot.Control"
  5.                             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  6.                             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  7.                             xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  8.                             xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
  9.                             FontFamily="{StaticResource PhoneFontFamilyNormal}"
  10.                             FontSize="{StaticResource PhoneFontSizeNormal}"
  11.                             Foreground="{StaticResource PhoneForegroundBrush}"
  12.                             Orientation="Portrait"
  13.                             SupportedOrientations="Portrait"
  14.                             shell:SystemTray.IsVisible="True"
  15.                             mc:Ignorable="d">
  16.  
  17.     <!--  LayoutRoot is the root grid where all page content is placed  -->
  18.     <Grid x:Name="LayoutRoot" Background="Transparent">
  19.         <!--  Pivot Control  -->
  20.         <control:ExtendedPivot HeaderVisibility="{Binding Visibility}" Title="MY APPLICATION">
  21.             <control:ExtendedPivotItem Header="item 1">
  22.                 <Grid>
  23.                     <TextBlock Text="item1" />
  24.                     <Button Click="ButtonBase_OnClick" Content="button" />
  25.                 </Grid>
  26.             </control:ExtendedPivotItem>
  27.  
  28.             <control:ExtendedPivotItem Header="item 2">
  29.                 <TextBlock Text="item2" />
  30.             </control:ExtendedPivotItem>
  31.         </control:ExtendedPivot>
  32.     </Grid>
  33. </phone:PhoneApplicationPage>

Line 4 defines the namespace that holds the ExtendedPivot. Line 20 puts the control on the actual page. Notice that we bind the HeaderVisibility property of our control. I defined the datacontext of this page in code behind to be of type MainViewModel. MainViewModel implements INotifyPropertyChanged and only holds one property of type Visibility, that property is bound to the ExtendedPivot’s HeaderVisibility.

The Button in the pivot will switch the HeaderVisibility between Collapsed and Visible, this happens in the code behind of this page.

Code Snippet
  1. publicpartialclassMainPage : PhoneApplicationPage
  2. {
  3.     privateMainViewModel _mainViewModel;
  4.  
  5.     // Constructor
  6.     public MainPage()
  7.     {
  8.         InitializeComponent();
  9.  
  10.         _mainViewModel = newMainViewModel();
  11.  
  12.         DataContext = _mainViewModel;
  13.     }
  14.  
  15.     privatevoid ButtonBase_OnClick(object sender, RoutedEventArgs e)
  16.     {
  17.         if (_mainViewModel.Visibility == Visibility.Collapsed)
  18.         {
  19.             _mainViewModel.Visibility = Visibility.Visible;            
  20.         }
  21.         else
  22.         {
  23.             _mainViewModel.Visibility = Visibility.Collapsed;          
  24.         }
  25.     }
  26. }

Not really the best way of writing a Windows Phone app but it’s just for making the point Glimlach

Conclusion

Extending a Windows Phone control isn’t hard as long as you follow the naming conventions, adding some extra functionality is as easy as copying the xaml template and adding some dependency properties.

The sample code can be found on my SkyDrive

 


Tags:

.Net | Binding | Devices | WP7 | WP8 | XAML

Presenting at Multi-mania

by Nico

Today I delivered a session at Europe’s biggest free multimedia conference. The session was an introductory session on Windows Phone 8. As promised during the session, here are the slides

The demos can be found on my SkyDrive

In case you’re interested in the session but couldn’t make it to Multi-mania, I’ve delivered this talk before as an MSDN webcast and there’s a recording of that session.

 


Tags:

.Net | Community | Presenting | WP8 | XAML

Taking over MSDN BeLux

by Nico

The Belgian MSDN team started an initiative a few weeks ago. They give the password to the MSDNBeLux Twitter account to someone from the community, that person gets to tweet about his favorite Microsoft technology for an entire week.

This week it’s my turn, so if you follow the MSDN Belux Twitter account, expect to see some Windows Phone related tweets popping up!


Tags:

Community

Porting a real win8 app to WP8–part 3

by Nico

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

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

PCL is improving

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

Changes in my project

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

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

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

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

Sharing ViewModels

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

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

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

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

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

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

 

Mission accomplished!

Conclusion

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

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

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

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


Tags:

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

MSDN webcast SignalR and WP8 slides and demos

by Nico

I had the pleasure of presenting an MSDN webcast on SignalR and Windows Phone 8 yesterday. I had a great time presenting and believe it or not, all demos actually worked! (it was live coding)

The stream was recorded and will be available on Channel 9 soon, in the meantime you can download the demos here (the chat application in the download also has a Windows 8 client as an added bonus).

This slides are on SlideShare.



Tags:

.Net | Community | MSDN | WP8 | signalr | Presenting

10 things you might have missed about MVVM Light

by Nico

Ever since I started playing with XAML based technologies (which actually isn’t that long ago) I’ve been looking into the MVVM (Model – View – ViewModel) pattern. I stumbled across MVVM Light pretty soon and liked the way it worked. Turns out I’m not the only one that likes it, there’s a whole set of developers, both hobby and professional, that really love this set of libraries. MVVM Light is, according to the author, not a framework but a set of libraries that take care of the plumbing to set up an MVVM structure and provide some extra helper classes to make life easier.

MVVM Light has changed a lot in its history, some elements were dragged out, others dragged in. Fact remains that it’s a fast, easy to use and lightweight framework. The author, Laurent Bugnion, does a great job of listening to the people that use MVVM Light, incorporating requested features and helping developers out. While talking to some of my fellow developers I’ve noticed a few times that there are certain elements of MVVM Light that others hadn’t heard of, and the same goes in the other direction. I’ve learned a lot of new things about MVVM Light just from talking with other users. Thinking about that gave me the idea of this blogpost and since those “10 things about…” posts seem to be popular, this was my chance. So here are my top 10 hidden gems of MVVM Light that you might have missed.

1. The MVVM Light installer

This one might seem a bit obvious, but in this NuGet driven world we would forget the added benefit of an installer. MVVM Light has an MSI installer that not only installs the binaries on your drive but it also provides project and itemtemplates in Visual Studio, along with a list of snippets. In case the Visual Studio 2012 update 2 removed your templates, reinstall the VSIX from C:\Program Files (x86)\Laurent Bugnion (GalaSoft)\Mvvm Light Toolkit\Vsix that should put the project templates back in place.

2. Constructor injection

This one is just awesome, and is actually a feature that can be found in most DI frameworks. MVVM Light uses SimpleIoc to register viewmodels and service classes at application launch (or during the app lifetime). Constructor injection means that you can specify a parameter in a class his constructor. When that class gets instantiated SimpleIoc will try to find a registered class of the same type as the parameter, when it finds one, that instance will get injected as the parameter of the constructor. Here’s an example, let’s say that in the ViewModelLocator, we register a navigation service.

Code Snippet
  1. SimpleIoc.Default.Register<INavigationService, NavigationService>();

We state here that we want to register an INavigationService in the IOC container, when it creates the instance we want it to be of type NavigationService. This “record” in the IOC container doesn’t have an instance yet, it gets instantiated when we fetch it from the container the first time. There are some occasions where you would want to create an instance of a class immediately when it gets registered. the Register<T> function of SimpleIoc has an overload to do just that.

Code Snippet
  1. SimpleIoc.Default.Register<INavigationService, NavigationService>(true);

Just pass in true as a parameter and it will create an instance right there and then.

Now we want to use the NavigationService in the MainViewModel.

Code Snippet
  1. ///<summary>
  2. /// Initializes a new instance of the MainViewModel class.
  3. ///</summary>
  4. public MainViewModel(INavigationService navigationService)
  5. {
  6.     
  7. }

SimpleIoc will search for a registered class of type INavigationService and will inject it in this constructor. This saves us the hassle of manually contacting the IOC container and requesting the correct instance.

WARNING: do be careful with this, the order in which you register your classes with the IOC container can be important, especially when using the overload to create instances. If I would create the MainViewModel before the NavigationService is registered I would get a nullreference exception. So be aware of that.

3. SimpleIoc to simple? replace it!

The SimpleIoc library works great and is a cool, lightweight addition to MVVM Light, but it is actually really lightweight. It is a very realistic scenario that for larger apps the SimpleIoc just won’t do (or you’re like me and want to try out how hard it is to replace it with another one). In this example I’m going to replace SimpleIoc with AutoFac, another well known and very powerful IOC service.

First of all, we’re going to need the AutoFac libraries and the extra library that allows us to use the ServiceLocator, just like SimpleIoc does. So either from the package manager console or from the UI, add the CommonServiceLocator extra for AutoFac, the AutoFac libraries are a dependency so they’ll get installed as well. I’m using a brand new Windows Phone 8 project for this, started from the MVVM Light project template.

Code Snippet
  1. Install-Package Autofac.Extras.CommonServiceLocator

The only place we’ll need to change some code is in the ViewModelLocator.

This is the new ViewModelLocator constructor, I’ve put the old SimpleIoc code in comments so it’s easy to compare

Code Snippet
  1. static ViewModelLocator()
  2. {
  3.     var container = newContainerBuilder();
  4.  
  5.     //ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
  6.     ServiceLocator.SetLocatorProvider(() => newAutofacServiceLocator(container.Build()));
  7.  
  8.     if (ViewModelBase.IsInDesignModeStatic)
  9.     {
  10.         //SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
  11.         container.RegisterType<Design.DesignDataService>().As<IDataService>();
  12.     }
  13.     else
  14.     {
  15.         //SimpleIoc.Default.Register<IDataService, DataService>();
  16.         container.RegisterType<DataService>().As<IDataService>();
  17.     }
  18.  
  19.     //SimpleIoc.Default.Register<MainViewModel>();
  20.     container.RegisterType<MainViewModel>();
  21. }

And that’s it, we declare a ContainerBuilder, set it as the LocatorProvider. The container is then used to register everything we need. The SimpleIoc overload that creates an instance upon registering would look something like this in AutoFac.

Code Snippet
  1. container.RegisterInstance(newDataService()).As<IDataService>();

That’s it, constructor injection should still work exactly like before with SimpleIoc.

4. Built-in messages

MVVM Light has something called the messenger, it registers classes as listeners and can send messages to them. This is commonly used to do communication between viewmodels. Generally I would create a message class for each type of message that I want to send, but MVVM Light has some build in messages that we can use.

GenericMessage<T>(T content) A message that can contain whatever of type T.

Code Snippet
  1. Messenger.Default.Send(newGenericMessage<string>("my message"));
NotificationMessage(string notification)a message that contains a notification. this might be
used to send a notification to a notification factory that will show the message in the preferred way.
Code Snippet
  1. try
  2. {
  3.     //try something
  4. }
  5. catch (Exception ex)
  6. {
  7.     Messenger.Default.Send(newNotificationMessage(ex.Message));
  8. }

There’s also a NotificationMessage<T>(T notification) should you need it.

The next one is NotificationMessageAction(string notification, Action callback) basically the same as the NotificationMessage but you can add a callback action that will fire once the message is received. This one also has the generic implementation just like NotificationMessage.

DialogMessage(string content, Action<MessageBoxResult> callback) 
This message is meant to ask the user to input something and it will return the result of that input in the
MessageBoxResult. MessageBoxResult is an enum that lives in System.Windows
Code Snippet
  1. publicenumMessageBoxResult
  2. {
  3.   None = 0,
  4.   OK = 1,
  5.   Cancel = 2,
  6.   Yes = 6,
  7.   No = 7,
  8. }

 

Code Snippet
  1. Messenger.Default.Send(newDialogMessage("Are you sure?", result =>
  2.     {
  3.         if (result == MessageBoxResult.Yes)
  4.         {
  5.             //do something
  6.         }
  7.     }));

The DialogMessage class inherits from GenericMessage<string>

PropertyChangedMessage(T oldValue, T newValue, string propertyName)
The PropertyChangedMessage is meant to use like the RaisePropertyChanged implementation. This is great when multiple 
viewmodels need to respond to a changed property.
Code Snippet
  1. publicstring WelcomeTitle
  2. {
  3.     get
  4.     {
  5.         return _welcomeTitle;
  6.     }
  7.  
  8.     set
  9.     {
  10.         if (_welcomeTitle == value)
  11.         {
  12.             return;
  13.         }
  14.  
  15.         Messenger.Default.Send(newPropertyChangedMessage<string>(_welcomeTitle, value, "WelcomeTitle"));
  16.  
  17.         _welcomeTitle = value;
  18.         RaisePropertyChanged(WelcomeTitlePropertyName);
  19.     }
  20. }

Be careful when registering listeners, try to use as many different types of messages as makes sense. You don’t want a wrong listener to receive a message because it happens to listen to the same type of message. To register a listener do this:

Code Snippet
  1. Messenger.Default.Register<PropertyChangedMessage<string>>(this, message =>
  2.     {
  3.         var a = message.NewValue;
  4.         //do something
  5.     } );

5. Portable libraries

MVVM Light is available on every XAML based platform. And it comes with a portable version now. The portable version is a separate library on NuGet.

Code Snippet
  1. Install-Package Portable.MvvmLightLibs

If you decide to use the portable version, make sure that every project in your solution that needs the MVVM Light libraries references the portable version. It does not work together with the “normal” MVVM Light libraries. When you use the PCL version, you can put your viewmodels in a separate, portable library and share them over, for example, a Windows Store and a Windows Phone app.

6. Event to Command behavior

MVVM Light has an ICommand implementation called RelayCommand that can be used to bind commands to actions. Like for example a button in XAML has a Command property that can be bound to an ICommand on its datacontext, so that when the button is clicked the ICommand will fire. Unfortunately not every XAML UI element has a bindable command property for every event that they can trigger and that’s where EventToCommand comes into play. With EventToCommand you can bind any event from a XAML UI element to an ICommand in the viewmodel.

First we’ll need two namespaces in our XAML page

Code Snippet
  1. xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
  2. xmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP8"

Let’s say that we want to use the Tap event on a stackpanel.

Code Snippet
  1. <StackPanel Grid.Row="0" Orientation="Horizontal">
  2.     <i:Interaction.Triggers>
  3.         <i:EventTrigger EventName="Tap">
  4.             <command:EventToCommand Command="{Binding GoToCommand}" CommandParameter="Edit" />
  5.         </i:EventTrigger>
  6.     </i:Interaction.Triggers>

Line 3 specifies the event that we want to handle, note that this is a string so be aware of typos. Line 4 binds the actual command and can even pass a parameter to the ICommand implementation.

Code Snippet
  1. privateRelayCommand<string> _goToCommand;
  2. publicRelayCommand<string> GoToCommand
  3. {
  4.     get { return _goToCommand jQuery15206875578026641675_1366095632942 (_goToCommand = newRelayCommand<string>(NavigateAway)); }
  5. }

The NavigateAway method has this signature

Code Snippet
  1. privatevoid NavigateAway(string parameter)

The parameter will be the word “Edit” in this case as that’s what we’ve specified in the XAML. We can even pass the eventargs from the event to the Command by changing line 4 from the XAML snippet to this

Code Snippet
  1. <command:EventToCommand PassEventArgsToCommand="True" Command="{Binding GoToCommand}" />

Windows Store applications don’t have these behaviors out of the box so you won’t be able to use EventToCommand there unless you install the Win8nl toolkit from NuGet. Joost Van Schaik has build his own implementation of behaviors in WinRT and thanks to his efforts (and of some other people that have helped in the project) we can now use EventToCommand in WinRT.

7. DispatcherHelper

Since .net 4.5 we have the await/async keywords and being the good little citizens that we are we do a lot of stuff async now. That means if we want to update something that lives on the UI thread we’ll need the Dispatcher class to marshall our action to that thread. Normally we don’t have access to the Dispatcher from our viewmodel classes. MVVM Light contains a DispatcherHelper that will execute an action on the UI thread when needed.

Code Snippet
  1. DispatcherHelper.CheckBeginInvokeOnUI(() =>
  2.     {
  3.         //do something
  4.     });

The DispatcherHelper gets initialized in the App.xaml.cs in the InitializePhoneApplication method (in a WP8 project that is).

DispatcherHelper also has a RunAsync method. The difference with the CheckBeginInvokeOnUI is that the CheckBeginInvokeOnUI will first check if it’s already on the UI thread, if it is it will just execute the action, if it isn’t it will call the RunAsync method.

8. Blendable

MVVM Light has complete Blend support, meaning you can drag and drop properties from the viewmodel onto the view to generate a binding, or you can generate design time data based on the datacontext and so on. I’m really not that good in Blend so I’m not going into detail about this one, just remember that MVVM Light was build with Blend in mind.

9. Open Source

This one you probably knew but MVVM Light is completely open source. http://mvvmlight.codeplex.com/ is the place to be if you want to dive into the source code.

10. Laurent is on Twitter and he’s a nice guy Glimlach

Laurent Bugnion, the founder of MVVM Light, is on Twitter! https://twitter.com/LBugnion he’s a great guy to chat with and very eager to help out anyone who needs help.

 

Conclusion

MVVM Light is a great library with a few hidden gems. In this article I’ve discussed 8 very interesting ones that can make your life as a developer easier. I’ve included two more extra items because 10 is a prettier number than 8 Glimlach

 

 


Tags:

.Net | MVVM Light | Windows 8 | WinRT | WP7 | WP8 | XAML

WP8, Leap Motion and a glue called Sockets

by Nico

I’m one of the lucky few who got their hands on a Leap Motion developer device (check out the video above if you’ve never heard of the Leap Motion). It’s a pretty cool device that gives you motion tracking not unlike Kinect but limited to finger and hand movement instead of complete body tracking.

I had the device and needed something to play with and what’s cooler then combining a cool gadget with an awesome smartphone? So I decided to build a small proof-of-concept that would capture finger movement in a WPF application and translate that movement to a moving ellipse in a Windows Phone application.

The Leap Motion’s documentation got me to a moving ellipse in a WPF application pretty fast thanks to the samples and documentation found on their developer portal. It took me a bit more time to get the position of the ellipse send to the phone, I wanted to use Sockets for this (SignalR would be way easier but I didn’t want an extra service running, now I have peer to peer communication).

Here’s how I did it

WPF and the Leap Motion

First, the WPF project. This project will be the socket server and the app that captures the Leap Motion’s output. The application only has one page with this as XAML

Code Snippet
  1. <Window x:Class="LeapWpPoc.MainWindow"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         Title="MainWindow"
  5.         Width="525"
  6.         Height="350">
  7.     <Canvas x:Name="TheCanvas">
  8.         <Ellipse x:Name="TheEllipse"
  9.                  Canvas.Left="211"
  10.                  Canvas.Top="118"
  11.                  Width="70"
  12.                  Height="70"
  13.                  Fill="#FFFF0C00"
  14.                  Stroke="Black" />
  15.         <TextBlock x:Name="TextBlockStatus"
  16.                    Canvas.Left="10"
  17.                    Canvas.Top="10"
  18.                    Foreground="Red"
  19.                    Text="Not connected"
  20.                    TextWrapping="Wrap" />
  21.     </Canvas>
  22. </Window>

Let’s have a look at how to interact with the Leap Motion first.

First thing you need when working with the Leap Motion (apart from the actual device that is) is a reference to LeapCSharp.NET4.0.dll however, you’ll also need Leap.dll and LeapCSharp.dll. Now I find this a bit dirty and I sincerely hope that the Leap Motion team will find a way to fix this but those two libraries aren’t referencable in our project but they need to be present in the application’s directory or it won’t work. What I did is add them as an existing item to the project, set their build action to Content and Copy if newer, at least this way they will always get copied into the build directory of the application.

Next, you’ll needs a class that inherits from Listener (Listener is part of the Leap Motion SDK). Listener is a base class that provides a bunch of virtual methods like OnExit, OnDisconnect, OnConnect and OnFrame. Feel free to override those to add some logging or logic but I’m only using the OnFrame method here. Here’s my Listener class

Code Snippet
  1. class PocListener : Listener
  2. {
  3.     public event EventHandler<FrameDetectedEventArgs> FrameDetected;
  4.  
  5.     public override void OnFrame (Controller controller)
  6.     {
  7.         // Get the most recent frame and report some basic information
  8.         Frame frame = controller.Frame ();
  9.  
  10.         if (FrameDetected != null)
  11.         {
  12.             FrameDetected(this, new FrameDetectedEventArgs(frame));
  13.         }
  14.     }
  15. }

The OnFrame method fires constantly, passing all the movement information, if any, in a frame. If my listener implementation detects a frame the FrameDetected event will fire, passing in the detected frame as an eventarg, FrameDetectedEventArgs is a very basic class that only passes the frame data to whoever is listening to the event.

Code Snippet
  1. public class FrameDetectedEventArgs : EventArgs
  2. {
  3.     public Frame Frame { get; set; }
  4.  
  5.     public FrameDetectedEventArgs(Frame frame)
  6.     {
  7.         Frame = frame;
  8.     }
  9. }

Notice that the OnFrame method needs a Controller as parameter? Controller is the class from the Leap Motion API that talks to the device. I create a new instance of Controller and my Listener in the MainWindow constructor.

Code Snippet
  1. private Frame _previousFrame;
  2. private Frame _currenFrame;
  3. private readonly PocListener _listener;
  4. private readonly Controller _controller;
  5. private readonly SocketFactory _socketFactory;
  6.  
  7. public MainWindow()
  8. {
  9.     InitializeComponent();
  10.  
  11.     _listener = new PocListener();
  12.     _controller = new Controller();
  13.  
  14.     // Have the sample listener receive events from the controller
  15.     _controller.AddListener(_listener);
  16.  
  17.     _listener.FrameDetected += ListenerOnFrameDetected;
  18. }

This is the constructor and some private fields, I need to keep track of both the current frame and the previous one to detect if there’s any change in the position of the hand or fingers. I also have an instance of PocListener (my own Listener class) and of Controller, both get instantiated in the constructor.Next I need to register my Listener in the Controller, that’s done on line 14 and then finally I attach an event handler to the FrameDetected event.

The event handler of the FrameDetected event will be responsible of checking if hands and fingers are detected.

Code Snippet
  1. private void ListenerOnFrameDetected(object sender, FrameDetectedEventArgs frameDetectedEventArgs)
  2. {
  3.     _currenFrame = frameDetectedEventArgs.Frame;
  4.  
  5.     if (!_currenFrame.Hands.Empty)
  6.     {
  7.         // Get the first hand
  8.         Hand hand = _currenFrame.Hands[0];
  9.  
  10.         // Check if the hand has any fingers
  11.         FingerList fingers = hand.Fingers;
  12.         if (!fingers.Empty)
  13.         {
  14.             if (_previousFrame == null) _previousFrame = _currenFrame;
  15.             //check if the current frame is different from the last frame
  16.             if (_currenFrame != _previousFrame)
  17.             {
  18.                 //we only need one finger so we'll take the first one that's detected
  19.                 Finger finger = fingers[0];
  20.  
  21.                 float x = _previousFrame.Fingers[0].TipPosition.x - finger.TipPosition.x;
  22.                 float y = _previousFrame.Fingers[0].TipPosition.y - finger.TipPosition.y;
  23.  
  24.                 //update the sphere's position
  25.                 Dispatcher.BeginInvoke((Action)(() =>
  26.                                                 {
  27.                                                     Canvas.SetTop(TheEllipse, Canvas.GetTop(TheEllipse) + y);
  28.                                                     Canvas.SetLeft(TheEllipse, Canvas.GetLeft(TheEllipse) - x);
  29.                                                 }));
  30.  
  31.                 //set this frame as the previous one and get ready to receive a new frame
  32.                 _previousFrame = _currenFrame;
  33.             }
  34.         }
  35.     }
  36. }

First we check if the previous frame has the same information as the current frame, if it does there’s no need to update the ellipse’s position.

If a hand and fingers are detected I select the first detected finger, because that’s currently the only one I’m interested in. Since all the Leap Motion actions are happening on a separate thread I need to invoke the UI thread to update the ellipse’s position, that’s what’s happening on line 25. The position of a UIElement in a Canvas in XAML is set through attached properties (Canvas.Left=”177” for example) to set these in code we use Canvas.SetLeft. To determine the new location of the ellipse I take the X and Y positions of the first finger in the previous frame and substract the X and Y of the first finger in the current frame. The new Y value gets added to the Canvas.Top of the ellipse and the new X value gets subtracted  from the Canvas.Left value. Last but not least I set the previousframe to the currentframe.

That’s all the code you need to get an ellipse moving in a canvas with the Leap Motion. So part 1 is a great success. Now onto the bigger challenge, getting a similar ellipse to move in a Windows Phone project.

Windows Phone and sockets

Implementing sockets to make devices talk to each other over the wire can be challenging but it’s also very rewarding and just plain fun once it works. I haven’t worked with sockets before so I had a real blast trying to figure this out and I went through the roof once that ellipse started moving on the Windows Phone emulator Glimlach. Before we dive into the sockets, let’s have a quick look at the MainPage.

Code Snippet
  1. <Canvas x:Name="TheCanvas">
  2.     <Ellipse x:Name="TheEllipse"
  3.              Canvas.Left="302"
  4.              Canvas.Top="186"
  5.              Width="70"
  6.              Height="70"
  7.              Fill="#FFFF0C00"
  8.              Stroke="Black" />
  9.     <TextBlock x:Name="TextBlockStatus"
  10.                Canvas.Left="10"
  11.                Canvas.Top="10"
  12.                Foreground="Red"
  13.                Text="Not connected"
  14.                TextWrapping="Wrap" />
  15. </Canvas>

Exactly the same controls as in the WPF project, nothing spectacular here. Let’s have a look at the code behind the MainPage.

Code Snippet
  1. public partial class MainPage
  2. {
  3.     private SocketClient _client;
  4.     const int Port = 8000;
  5.     private const string IpAddress = "10.16.79.70";
  6.  
  7.     // Constructor
  8.     public MainPage()
  9.     {
  10.         InitializeComponent();
  11.         _client = new SocketClient();
  12.  
  13.         _client.OnConnected += (sender, args) => Dispatcher.BeginInvoke(() =>
  14.             {
  15.                 TextBlockStatus.Text = "Connected";
  16.                 TextBlockStatus.Foreground = new SolidColorBrush(Colors.Green);
  17.             });
  18.         _client.OnMessageReceived += (sender, args) => Dispatcher.BeginInvoke(() => MoveBall(args.Response));
  19.         _client.Connect(IpAddress, Port);
  20.  
  21.         _client.Receive();
  22.     }
  23.  
  24.     private void MoveBall(string response)
  25.     {
  26.         response = response.Replace(',', '.');
  27.         var coordinates = response.Split(';');
  28.  
  29.         float y = float.Parse(coordinates[0]);
  30.         float x = float.Parse(coordinates[1]);
  31.  
  32.         Canvas.SetTop(TheEllipse, y);
  33.         Canvas.SetLeft(TheEllipse, x);
  34.     }
  35. }

First some fields, don’t worry about the SocketClient class, we’ll get to that in a minute. Some constants holding the IP address and the port of the server (don’t forget to change this IP address to the address of your own pc!)

In the constructor we instantiate the SocketClient instance and handle its two events. The OnConnected event is going to change the text of the TextBlock to “Connected” and the OnMessageReceived event handler will move the ellipse.

The MoveBall() method will do the actual moving. The message that we will receive will be a string that has the Y and X of the ellipse in the WPF application seperated by a semicolon. The problem I had here was that instead of a dot to separate the decimals .NET had changed it into a comma (which is the default decimal sign in Belgium) so I need to change that back. I then split up the string using the semicolon as split character, parse the values into a float and set the ellipse to its new position. Let’s get serious and dive into the socket stuff now.

Sockets provide us with TCP and UDP communication, next to a whole bunch of other features. This app will use a TCP connection between WPF and a Windows Phone application. Since we’re currently looking at the Windows Phone app, let’s continue there. I’ve added a class called SocketClient that takes care of connection a socket, sending and receiving messages. Let’s start with the fields and constructor.

Code Snippet
  1. // Cached Socket object that will be used by each call for the lifetime of this class
  2. Socket _socket;
  3.  
  4. // Signaling object used to notify when an asynchronous operation is completed
  5. static ManualResetEvent _clientDone;
  6.  
  7. // Define a timeout in milliseconds for each asynchronous call. If a response is not received within this
  8. // timeout period, the call is aborted.
  9. const int TimeoutMilliseconds = 5000;
  10.  
  11. // The maximum size of the data buffer to use with the asynchronous socket methods
  12. const int MaxBufferSize = 2048;
  13.  
  14. public event EventHandler<MessageReceivedEventArgs> OnMessageReceived;
  15. public event EventHandler OnConnected;
  16.  
  17. public SocketClient()
  18. {
  19.     _clientDone = new ManualResetEvent(false);
  20. }

First field is the actual socket that we’ll be using, second one is a reset event that we can use to make a thread block while waiting for an event to fire. The timeout is the max amount of time that the reset event will block a thread. The buffersize is the size of the buffer for socket messages. The two events are fired when the app receives a socket message or when a socket connects.

The most important function of the SocketClient class that I’m building here is to connect two sockets.

Code Snippet
  1. public string Connect(string hostName, int portNumber)
  2. {
  3.     string result = string.Empty;
  4.  
  5.     // Create DnsEndPoint. The hostName and port are passed in to this method.
  6.     DnsEndPoint hostEntry = new DnsEndPoint(hostName, portNumber);
  7.  
  8.     // Create a stream-based, TCP socket using the InterNetwork Address Family.
  9.     _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  10.  
  11.     // Create a SocketAsyncEventArgs object to be used in the connection request
  12.     SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs {RemoteEndPoint = hostEntry};
  13.  
  14.     socketEventArg.Completed += (sender, args) =>
  15.                                         {
  16.                                             // Retrieve the result of this request
  17.                                             result = args.SocketError.ToString();
  18.  
  19.                                             // Signal that the request is complete, unblocking the UI thread
  20.                                             _clientDone.Set();
  21.  
  22.                                             if (OnConnected == null) return;
  23.  
  24.                                             OnConnected(this, new EventArgs());
  25.                                         };
  26.  
  27.     // Sets the state of the event to nonsignaled, causing threads to block
  28.     _clientDone.Reset();
  29.  
  30.     // Make an asynchronous Connect request over the socket
  31.     _socket.ConnectAsync(socketEventArg);
  32.     
  33.     // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
  34.     // If no response comes back within this time then proceed
  35.     _clientDone.WaitOne(TimeoutMilliseconds);
  36.  
  37.     return result;
  38. }

The connect method takes in two parameters, the hostname (or IP address) and the portnumber of the socket we want to connect to. Based on these two parameters we create a DnsEndPoint that will be passed to the server socket as being the remote endpoint so that the server socket knows where to send his messages. Next we instantiate the Socket, stating that it’s using an internal IPv4 network, a stream socket and the TCP protocol. Now that we have a socket and an endpoint we’ll need some eventargs, those args will be passed onto the server. Once the connection succeeds (or fails) the Completed event on the SocketAsyncEventArgs will fire, in that event handler we’ll trigger the OnConnected event. With that in place we call the Reset() method on the ManualResetEvent to set the event to nonsignaled, call the ConnectAsync() method on the Socket and pass in the eventargs and finally blocking the thread for a certain time to allow the socket time to connect.

So now that our client can connect to a socket, let’s build something to send messages to the connected socket. From the Windows Phone 8 version it looks like this

Code Snippet
  1. public void Send(string data)
  2. {
  3.     data = data + "<EOF>";
  4.  
  5.     if (_socket != null)
  6.     {
  7.         SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs
  8.             {
  9.                 RemoteEndPoint = _socket.RemoteEndPoint,
  10.                 UserToken = null
  11.             };
  12.  
  13.         socketEventArg.Completed += (sender, args) =>
  14.                                         {
  15.                                             _clientDone.Set();
  16.                                         };
  17.  
  18.         // Add the data to be sent into the buffer
  19.         byte[] payload = Encoding.UTF8.GetBytes(data);
  20.         socketEventArg.SetBuffer(payload, 0, payload.Length);
  21.  
  22.         // Sets the state of the event to nonsignaled, causing threads to block
  23.         _clientDone.Reset();
  24.  
  25.         // Make an asynchronous Send request over the socket
  26.         _socket.SendAsync(socketEventArg);
  27.  
  28.         // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
  29.         // If no response comes back within this time then proceed
  30.         _clientDone.WaitOne(TimeoutMilliseconds);
  31.     }
  32. }

We get in the message as a parameter, at the end of the message I add “<EOF>” just to make sure that I only get the part that I need at the server side and that the message has been delivered in full. If at this point the socket is null then it isn’t connected yet. If it isn’t we once again instantiate SocketAsyncEventArgs. The data gets serialized into a byte array and set as a buffer in the eventargs. Set the ManualResetEvent to nonsignaled, start sending the message over the socket async and block the thread.

And last but not least there’s the code to receive messages on the socket.

Code Snippet
  1. public void Receive()
  2. {
  3.     if (_socket != null)
  4.     {
  5.         SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs
  6.             {
  7.                 RemoteEndPoint = _socket.RemoteEndPoint
  8.             };
  9.  
  10.         // Setup the buffer to receive the data
  11.         socketEventArg.SetBuffer(new Byte[MaxBufferSize], 0, MaxBufferSize);
  12.  
  13.         socketEventArg.Completed += (sender, args) =>
  14.             {
  15.                 if (args.SocketError == SocketError.Success)
  16.                 {
  17.                     // Retrieve the data from the buffer
  18.                     string response = Encoding.UTF8.GetString(args.Buffer, args.Offset, args.BytesTransferred);
  19.                     response = response.Trim('\0');
  20.  
  21.                     if (response.Contains("<EOF>"))
  22.                     {
  23.                         response = response.Substring(0, response.IndexOf("<EOF>"));
  24.                         if (OnMessageReceived != null)
  25.                             OnMessageReceived(this, new MessageReceivedEventArgs(response));
  26.                     }
  27.  
  28.                     Receive();
  29.                 }
  30.  
  31.                 _clientDone.Set();
  32.             };
  33.  
  34.         // Sets the state of the event to nonsignaled, causing threads to block
  35.         _clientDone.Reset();
  36.  
  37.         // Make an asynchronous Receive request over the socket
  38.         _socket.ReceiveAsync(socketEventArg);
  39.  
  40.         // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
  41.         // If no response comes back within this time then proceed
  42.         _clientDone.WaitOne(TimeoutMilliseconds);
  43.     }
  44. }

So the same story with the null check on the socket and creating of the SocketEventArgs. Once the Completed event fires we’ll check if the receive was successful  and if the received message contains “<EOF>”, if it does we take everything before <EOF> and pass it in the MessageReceivedEventArgs that go with the MessageReceived event.

Code Snippet
  1. public class MessageReceivedEventArgs : EventArgs
  2. {
  3.     public string Response { get; set; }
  4.  
  5.     public MessageReceivedEventArgs(string response)
  6.     {
  7.         Response = response;
  8.     }
  9. }

Once everthing is handled we call the Receive method again so it’s ready to start receiving the next message.

And that’s basically all the logic for a socket connection on the Windows Phone side of things. The only thing left to do in the app is change the MainPage’s constructor to initialize the SocketClient and add some fields.

Code Snippet
  1. private SocketClient _client;
  2. const int Port = 8000;
  3. private const string IpAddress = "10.16.79.70";
  4.  
  5. // Constructor
  6. public MainPage()
  7. {
  8.     InitializeComponent();
  9.     _client = new SocketClient();
  10.  
  11.     _client.OnConnected += (sender, args) => Dispatcher.BeginInvoke(() =>
  12.         {
  13.             TextBlockStatus.Text = "Connected";
  14.             TextBlockStatus.Foreground = new SolidColorBrush(Colors.Green);
  15.         });
  16.     _client.OnMessageReceived += (sender, args) => Dispatcher.BeginInvoke(() => MoveBall(args.Response));
  17.     _client.Connect(IpAddress, Port);
  18.  
  19.     _client.Receive();
  20. }

The constructor instantiates the SocketClient, attaches an handler to the OnConnected event to update the textbox with the connection status and handle the OnMessageReceived event to update the position of the ellipse. Don’t forget to update the IP address to the one from your own pc!

Back to WPF!

Now that our Windows Phone app is ready, it’s time to implement the socket server. As mentioned before, the WPF app that gets input from the Leap Motion will serve as socket server.

I’ve added a class to the WPF project called SocketFactory, it serves the same function as the SocketClient class in the Windows Phone project but from a server point of view. The way to build and use a socket in full blown .net 4.5 differs a bit from how we did it in Windows Phone. First we’ll need a state class, this contains a socket, the buffersize, a byte array to function as the buffer and a stringbuilder to recompose the message.

Code Snippet
  1. // State object for reading client data asynchronously
  2. public class StateObject
  3. {
  4.     // Client  socket.
  5.     public Socket WorkSocket = null;
  6.     // Size of receive buffer.
  7.     public const int BufferSize = 1024;
  8.     // Receive buffer.
  9.     public byte[] Buffer = new byte[BufferSize];
  10.     // Received data string.
  11.     public StringBuilder Sb = new StringBuilder();
  12. }

Next, we’ll need some fields in the SocketFactory class

Code Snippet
  1. // Thread signal.
  2. public static ManualResetEvent AllDone = new ManualResetEvent(false);
  3. private StateObject _state;
  4. public event EventHandler OnConnected;

And here’s the function to receive a connection request

Code Snippet
  1. public void Start()
  2. {
  3.     IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
  4.     IPAddress ipAddress = ipHostInfo.AddressList[3];
  5.     IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 8000);
  6.  
  7.     Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  8.  
  9.     // Bind the socket to the local endpoint and listen for incoming connections.
  10.     try
  11.     {
  12.         listener.Bind(localEndPoint);
  13.         listener.Listen(100);
  14.  
  15.         while (true)
  16.         {
  17.             // Set the event to nonsignaled state.
  18.             AllDone.Reset();
  19.  
  20.             // Start an asynchronous socket to listen for connections.
  21.             Console.WriteLine("Waiting for a connection...");
  22.             listener.BeginAccept(AcceptCallback, listener);
  23.  
  24.             // Wait until a connection is made before continuing.
  25.             AllDone.WaitOne();
  26.  
  27.             if (OnConnected == null) return;
  28.  
  29.             OnConnected(this, new EventArgs());
  30.         }
  31.  
  32.     }
  33.     catch (Exception e)
  34.     {
  35.         Console.WriteLine(e.ToString());
  36.     }
  37. }

We declare a socket called listener, pass it the same parameters as we did for Windows Phone, stating that it’s local network, streaming and using the TCP protocol. We need to bind this socket to an IPEndPoint, to create an IPEndPoint we need an IPAddress and a port. Lines 3 and 4 are used to getting the computer’s IP address from its hostname. Once we have that we can bind the socket to the endpoint. Make sure that the port you set here is the same port you try to connect to in the Windows Phone app. Once the socket connects the callback fires, in the callback we start receiving data from the connected client.

Code Snippet
  1. public void AcceptCallback(IAsyncResult ar)
  2. {
  3.     // Signal the main thread to continue.
  4.     AllDone.Set();
  5.  
  6.     // Get the socket that handles the client request.
  7.     Socket listener = (Socket)ar.AsyncState;
  8.     Socket handler = listener.EndAccept(ar);
  9.  
  10.     // Create the state object.
  11.     _state = new StateObject { WorkSocket = handler };
  12.  
  13.     handler.BeginReceive(_state.Buffer, 0, StateObject.BufferSize, 0, ReadCallback, _state);
  14. }

Once data is received, the ReadCallback fires

Code Snippet
  1. public void ReadCallback(IAsyncResult ar)
  2. {
  3.     StateObject state = (StateObject)ar.AsyncState;
  4.     Socket handler = state.WorkSocket;
  5.  
  6.     int bytesRead = handler.EndReceive(ar);
  7.  
  8.     if (bytesRead > 0)
  9.     {
  10.         // There  might be more data, so store the data received so far.
  11.         state.Sb.Append(Encoding.ASCII.GetString(
  12.             state.Buffer, 0, bytesRead));
  13.  
  14.         // Check for end-of-file tag. If it is not there, read
  15.         // more data.
  16.         string content = state.Sb.ToString();
  17.         if (content.IndexOf("<EOF>") > -1)
  18.         {
  19.             Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
  20.                 content.Length, content);
  21.         }
  22.         else
  23.         {
  24.             // Not all data received. Get more.
  25.             handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReadCallback, state);
  26.         }
  27.     }
  28. }

We can get the stateobject and socket from the IAsyncResult and we start reading until we encounter “<EOF>”, once everything is received we write it out in the output window. Now in this example the server won’t actually be receiving any messages, I’ve just put in this method in case you want to enhance it or have some use for the code.

What is important in this sample is the Send method, this will send a message over the connected socket to the client.

Code Snippet
  1. public void Send(string data)
  2. {
  3.     Send(_state.WorkSocket, data);
  4. }
  5.  
  6. private void Send(Socket handler, string data)
  7. {
  8.     data = data + "<EOF>";
  9.     // Convert the string data to byte data using ASCII encoding.
  10.     byte[] byteData = Encoding.ASCII.GetBytes(data);
  11.  
  12.     // Begin sending the data to the remote device.
  13.     handler.BeginSend(byteData, 0, byteData.Length, 0, SendCallback, handler);
  14. }

I’ve split up the Send into two methods, the public one just receives the message we want to send and passes it trough to the private one, also passing in the socket to use. This way the application itself doesn’t need to worry about selecting a socket, let the socketFactory deal with that. The Send method adds the end of file part to the message, serializes it into a byte array and sends it over the socket. Once the send is complete, the callback will fire.

Code Snippet
  1. private void SendCallback(IAsyncResult ar)
  2. {
  3.     try
  4.     {
  5.         // Retrieve the socket from the state object.
  6.         Socket handler = (Socket)ar.AsyncState;
  7.  
  8.         handler.EndSend(ar);
  9.     }
  10.     catch (Exception e)
  11.     {
  12.         Console.WriteLine(e.ToString());
  13.     }
  14. }

I’m not really doing anything in the callback, but this would be the perfect place to check for successful delivery and maybe notifying the UI thread to show a confirmation or something similar.

Now that our socket infrastructure is in place and we have a client updating a UI based on the received messages, it’s time to finish this sample by letting the server send the coordinates of the ellipse. In the MainWindow add a field for the socket factory. (line 5 is the extra field)

Code Snippet
  1. private Frame _previousFrame;
  2. private Frame _currenFrame;
  3. private readonly PocListener _listener;
  4. private readonly Controller _controller;
  5. private readonly SocketFactory _socketFactory;

With the new field in place, replace (or update) the constructor to this

Code Snippet
  1. public MainWindow()
  2. {
  3.     InitializeComponent();
  4.  
  5.     _socketFactory = new SocketFactory();
  6.     _socketFactory.OnConnected += (sender, args) => Dispatcher.BeginInvoke((Action) (() =>
  7.         {
  8.             TextBlockStatus.Text = "Connected";
  9.             TextBlockStatus.Foreground = new SolidColorBrush(Colors.Green);
  10.         }));
  11.  
  12.     Task.Run(() => _socketFactory.Start());
  13.  
  14.     _listener = new PocListener();
  15.     _controller = new Controller();
  16.  
  17.     // Have the sample listener receive events from the controller
  18.     _controller.AddListener(_listener);
  19.  
  20.     _listener.FrameDetected += ListenerOnFrameDetected;
  21.  
  22.     Timer timer = new Timer(200);
  23.     timer.Elapsed += (sender, args) => Dispatcher.BeginInvoke((Action)(() =>
  24.         _socketFactory.Send(string.Format("{0};{1}", Canvas.GetTop(TheEllipse), Canvas.GetLeft(TheEllipse)))));
  25.  
  26.     timer.Start();
  27. }

We instantiate the SocketFactory, attach an handler for the OnConnected event to update the UI. The SocketFactory’s Start method is queued on the thread pool to run async, this way the UI thread will remain responsive. The Leap Motion get’s initialized and we start a timer. This timer will make sure that every 200 milliseconds the coordinates of the ellipse are send over the socket to the client. The sending of the message needs to be done on the UI thread because we need the ellipse’s coordinates, and that ellipse lives on the UI thread.

Now, why use a timer? In the first version of this sample a message was send every time the ellipse moved, this resulted in really really really poor performance, messages were being send faster than they arrived causing all kinds of weird behavior. Sending it every 200 milliseconds makes it move quite well.

Everything is in place now, so run it and move the ellipse around with the Leap Motion!

Conclusion

In this post I’ve explained my adventure of connecting the Leap Motion to a Windows Phone application by using sockets. While not the easiest thing to set up or use, sockets are a really powerful way of communicating between applications no matter what platform they’re on (as long as that platform supports sockets).

The Leap Motion is a great device. It’s small, light, has a very small footprint on your system and is just plain fun to mess around with. I could’ve used anything for a socket example but making something move on screen, on two devices at the same time by just moving your hand has something magically. The Leap Motion is definitely on my list of awesome gadgets.

The code for this post can be found on my Skydrive


Tags:

NUI | LeapMotion | .Net | Devices | WP8 | WPF

Sessions at NxtGenUG

by Nico

Last week I had the pleasure of travelling to the wonderful country of the United Kingdom (home of The Doctor!) to do some talks about Windows Azure Mobile Services and Windows Phone 8. I did a talk at the user group in Coventry and in Manchester. The response was great, a lot of people were impressed about the possibilities and the ease of use of WAMS. For those of you who’re interested, here’s my slide deck and the demo I build (live coding, didn’t fail, hooray for me Glimlach).

Download the demo


Tags:

Community | WP8 | Azure

Using MyGet for those common classes

by Nico

Every .net developer, be it a mobile, web or windows developer, uses (or should use) NuGet. A big, and fast growing, gallery of useful (and less useful but fun) libraries. The problem I was having with NuGet is that for every project I needed to go search in that big gallery for the packages I wanted. Luckily someone had the same problem and decided to do something about it. And so MyGet was born.

The MyGet team sells MyGet as Nuget-as-a-service. You can create your own feed, drop in the NuGet packages you tend to use (even mirror them) and add the feed into your package manager. This way you get your own personal gallery, no more searching for the ones you need, those feeds are public by the way, everyone can use them. If you want a private feed you’ll need to look at the MyGet price plans.

Getting started with MyGet is really easy, just go to http://www.myget.org log in with your Microsoft, Google, Yahoo, Facebook, OpenID, GitHub or StackOverflow account. After you login you can add feeds to your account.

Creating a feed is as easy as giving it a name and a description and selecting the feed type (public, community or private). Once your feed is created you can start adding packages to it. To add a package enter the search term just like you would do when you use NuGet in Visual Studio, click the package you want and click Add.

If you want, in the Add package dialog, you can select to mirror the package. This will copy the entire package from the NuGet feed into MyGet, meaning that you’ll still be able to install the package when NuGet goes down. To give you an idea of how a feed could look like, here’s some of the packages in my Windows Phone feed.

To use your freshly created feed you’ll need to add it as a package source in NuGet. Go to the Package Manager settings from the Visual Studio options menu (or open the Manage NuGet packages dialog in a project and click Settings). Here you can add a new package source.

Once added, the new package source will show up in NuGet and you’ll be able to install the packages from you own feed.

Managing my own package feed has really reduced the time I used to spent searching and adding packages. But the MyGet team has been working hard on a really cool feature.

Do the Wonka

The MyGet team (all Belgian developers by the way – hooray for Belgium Smile) developed a feature they codenamed “Wonka”. It’s currently in Beta but it’s working great so far. This is what Wonka is all about

They’ve setup their own Build server, including support for building Windows Phone 8 libraries (thanks to the command line compiler in the WP8 SDK). Hearing about such a cool feature and hearing that it’s in beta made me want to try it. And I started thinking, maybe I could put a bunch of classes that I tend to use in some form in multiple projects in one library and have that library in my feed.

The project itself is still very small but it will grow when I need extra functionality, it currently holds a Regex class to get rid of HTML tags in strings and a RestClient class that uses the portable HttpClient to do a Get operation. For reference, here are the classes.

Code Snippet
  1. publicstaticclassRegexHelper
  2. {
  3.     publicstaticstring RemoveHtmlTags(thisstring text)
  4.     {
  5.         //add some layout
  6.         text = Regex.Replace(text, "<br />", "\n");
  7.         text = Regex.Replace(text, "</p>", "\n");
  8.  
  9.         //replace weird characters
  10.         text = Regex.Replace(text, "&amp;", "&");
  11.         text = Regex.Replace(text, "&nbsp;", " ");
  12.  
  13.         //remove remaining HTML tags
  14.         returnRegex.Replace(text, @"<[^>]*>", string.Empty);
  15.     }
  16. }
Code Snippet
  1. publicclassRestClient : IRestClient
  2. {
  3.     privateHttpClient _client;
  4.  
  5.     publicasyncTask<T> Get<T>(CancellationToken cancellationToken, string url, bool includeResultProps = true)
  6.         where T : new()
  7.     {
  8.         try
  9.         {
  10.             _client = newHttpClient();
  11.  
  12.             var result = await _client.GetAsync(url);
  13.             string json = await result.Content.ReadAsStringAsync();
  14.  
  15.             if (!includeResultProps)
  16.             {
  17.                 JObject obj = JObject.Parse(json);
  18.                 json = obj["results"].ToString();
  19.             }
  20.  
  21.             returnJsonConvert.DeserializeObject<T>(json);
  22.         }
  23.         catch (JsonSerializationException e)
  24.         {
  25.             returnnew T();
  26.         }
  27.     }
  28. }

The project contains Json.net and the portable HttpClient, both referenced through NuGet. Now we need a way for the build server to get a hold of these packages, we can accomplish this by enabling the NuGet package restore. Right-click the solution and you’ll see the option right there.

This will add a .nuget folder to your solution that you’ll need to check-in into your source control.

So we have a working project with some classes that we would like to get into a NuGet package by using the MyGet build server. What we need to do is get this package into a repository. I used BitBucket for this because it has free private repositories. You can also add a GitHub or Codeplex repository.

If you use the from BitBucket button it will ask you for permission to access your account on BitBucket and will show you a list of all your repositories hosted there. Select the one you need and click Add. Do take notice of the warning.

Add the repository and click the edit button next to it. Enter your BitBucket credentials here so MyGet can access your private repository to fetch the sources. And that’s it, you can now hit the Build button to fetch the sources and try to build them. In my case this immediately resulted in a big fat red Failed message. The problem here is something of a chicken-egg problem (a big thanks here to the MyGet team for helping me figuring this one out!). So here’s the problem:

  • The project file needs the package to run
  • The project file is needed for package restore
  • package needs package restore

The solution here is to setup a build.bat in the solution folder. The MyGet build server will search for a build.bat to execute, if it doesn’t find one it will just use the sln available.

With the build.bat file we first fetch the necessary packages and then build the solution

Code Snippet
  1. @echo Off
  2. set config=%1
  3. if "%config%" == "" (
  4.    set config=Release
  5. )
  6.  
  7. set version=
  8. if not "%PackageVersion%" == "" (
  9.    set version=-Version %PackageVersion%
  10. )
  11.  
  12. REM Run package restore
  13. %nuget% install WindowsPhone\packages.config -OutputDirectory packages -Prerelease -NonInteractive
  14.  
  15. REM Build solution
  16. %WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild WindowsPhone.sln /p:Configuration="%config%" /m /v:M /fl /flp:LogFile=msbuild.log;Verbosity=Normal /nr:false

Add this to your solution in Visual Studio, make sure it’s called build.bat and check it into your source control. Now it should build.

Automating builds

Next step to make everything even more awesome is to add a hook to BitBucket so that MyGet will fetch and build the sources everytime a commit is pushed into the repository. First you’ll need the HTTP POST link from MyGet, you’ll find it underneath your build source.

Once you’ve got that link, go to the BitBucket repository and click the Settings icon, in the Settings go to Services and add a POST service.

Past the URL and save the service. Now everytime you push a commit to BitBucket a new build should get queued in MyGet (the page refreshes automatically to show the build process).

And just like that we’ve created a NuGet package in a MyGet feed with continuous delivery, how cool is this right? If I check my feed from Visual Studio my package shows up!

Conclusion

In this post I’ve explained how I use MyGet, a NuGet-as-a-service, to create a package feed with only the packages that are relevant for me. I’ve also explained how I’ve added my own library of classes that I use in multiple projects in that feed and setup continuous delivery so that the package gets updated with every commit that gets pushed to the repository.

Resources:

A big shout out to the MyGet team for helping me getting started with their awesome service! http://www.myget.org/Home/Team


Tags:

.Net | continuous delivery | myget | NuGet | PCL

Porting a real win8 app to WP8–part 2

by Nico

Porting a real win8 app to WP8 – part 1

In part one of my adventure I described the architecture of my app and how I managed to move all viewmodels into a PCL (portable class library) but I didn’t use them yet. The main consensus of part one was that I needed to do quite some refactoring and add a lot of abstractions to the project in order to move over viewmodels to PCL projects. In part 2 I’ll describe how I got the viewmodels to work and how I re-enabled page navigation in the Windows 8 version. And with a bit of luck in part 3 I’ll be talking about the Windows Phone 8 version of this app.

A small note on part 1

I wasn’t very happy with part 1 since I needed to create some extra layers and abstractions. Since then the Microsoft Techdays have come and gone and with that two very interesting sessions that made me rethink some stuff. The session were from Laurent Bugnion (his blog, his Twitter) (the creator of the awesome MVVM Light toolkit) and Gill Cleeren (his blog, his Twitter) (a Belgian Silverlight MVP, RD and Win8 enthusiast). From Laurent I learned some tips and tricks concerning the ViewModelLocator class and specifically how to correctly use it in a portable library (more on that in part 3 since I haven’t implemented it yet). Gill gave a session on advanced MVVM tactics and one sentence kept vibrating in my mind “an extra class doesn’t cost a thing” next to that his demo app was filled with layers of abstractions way beyond the extra layers I needed to add to get the project to build again. After that session I felt reassured that I was going down a pretty good path with the revised architecture I had build in part 1. If you want to take a look at that session yourself, the recording of the SilverlightShow version is available here.

About part 2

The last couple of days I found some spare time to mess around with the project again. I’m now at the stage where the Windows Store app is using the portable ViewModels and the navigation is working properly. Those parts are what I’ll discuss here.

Using the ViewModels

Having the portable ViewModels ready it was time to switch to them. I deleted every viewmodel that was still in my client project, except for the ViewModelLocator, that one will be moved later. I registered the new abstraction layers in the ViewModelLocator, making sure that this only happened at runtime, not at designtime and tried to build the app. I couldn’t believe my eyes when I saw the message “Build succeeded”. I replaced the viewmodels in my client project with the ones in the portable library and it still builds! In case you’re interested, this is what’s getting registered in my ViewModelLocator at this time.

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<INavigationService, NavigationService>();
  14.         SimpleIoc.Default.Register<IService, SDKBroker.WinRT.Service>();
  15.         SimpleIoc.Default.Register<IMessageApi, MessageApi>();
  16.         SimpleIoc.Default.Register<IFrameworkApi, FrameworkApi>();
  17.         SimpleIoc.Default.Register<IDispatcher, Dispatcher>();
  18.         SimpleIoc.Default.Register<INetworkApi, NetworkApi>();
  19.     }
  20.  
  21.     //register viewmodels
  22.     SimpleIoc.Default.Register<MainViewModel>();
  23.     SimpleIoc.Default.Register<VolumeDetailViewModel>(true);
  24.     SimpleIoc.Default.Register<CharacterDetailViewModel>(true);
  25.     SimpleIoc.Default.Register<TeamDetailViewModel>(true);
  26.     SimpleIoc.Default.Register<IssueDetailViewModel>(true);
  27.     SimpleIoc.Default.Register<SearchViewModel>();
  28.     SimpleIoc.Default.Register<DetailViewModel>(true);
  29.     SimpleIoc.Default.Register<StoryArcDetailViewModel>(true);
  30.     SimpleIoc.Default.Register<LocationDetailViewModel>(true);
  31.     SimpleIoc.Default.Register<PersonDetailViewModel>(true);
  32.     SimpleIoc.Default.Register<CollectionViewModel>();
  33.     SimpleIoc.Default.Register<NewsFeedViewModel>(true);
  34. }

Everything in the else block gets registered only at runtime. The viewmodels themselves can get registered at designtime just in case I ever want to incorporate designtime test data (something I really should do actually). Notice that some ViewModel registrations get passed a boolean parameter? The Register method of SimpleIoc has an optional parameter stating whether or not the object should get instantiated immediately. Since some viewmodels are listening for messages from the Messenger class in MVVM Light they need their instance right of the bat so they can register as listeners.

I tried to run the app, it started and data was coming in, I could use the button to show the search charm but no navigation was working. That made sense since all navigation commands are now going to ISomePage instead of SomePage and those interfaces weren’t doing anything yet. So I had to make every page implement the correct interface and put together a way to navigate to the correct page from the interface.

Implementing the interface is easy enough (they’re all just empty interfaces). Next problem was that those interfaces are inside of a folder called View in the ViewModel PCL and they need to be known in the Framework.WinRT project (that’s where the NavigationService lives). So I’ve added another PCL called it ComicDB.View and moved all interfaces there. (I couldn’t reference the ViewModel project in the Framework project, it would create a circular dependency). After adding all references everything was building again but still no navigation. To get this to work I changed the Navigate method on the NavigationService from this

Code Snippet
  1. publicvirtualbool Navigate(Type destination, object parameter = null)
  2. {
  3.     try
  4.     {
  5.         _rootFrame.Navigate(destination, parameter);
  6.  
  7.         returntrue;
  8.     }
  9.     catch (Exception e)
  10.     {
  11.         returnfalse;
  12.     }
  13. }

to this

Code Snippet
  1. publicvirtualbool Navigate(Type destination, object parameter = null)
  2. {
  3.     try
  4.     {
  5.         NavigateToPage(destination, parameter);
  6.  
  7.         returntrue;
  8.     }
  9.     catch (Exception e)
  10.     {
  11.         returnfalse;
  12.     }
  13. }
  14.  
  15. privatevoid NavigateToPage(Type destination, object parameter)
  16. {
  17.     try
  18.     {
  19.         //get the implementation for the view
  20.         var instance = SimpleIoc.Default.GetInstance(destination);
  21.         var type = instance.GetType();
  22.  
  23.         _rootFrame.Navigate(type, parameter);
  24.     }
  25.     catch (ActivationException)
  26.     {
  27.         //no registered type found, just navigate to the destination, maybe it's not an interface
  28.         _rootFrame.Navigate(destination, parameter);                                
  29.     }
  30. }

The Navigate method passes everything to the NavigateToPage method that tries to resolve a registered instance of the passed in type, should this fail it throws an ActivationException, in that case just try to navigate. This allows us to navigate to pages that don’t use any interface. Once we get the instance out of the IOC we get its type and pass that into the navigate command of the frame. Obviously, before this starts working we need to register the pages in the IOC and that happens in the ViewModelLocator.

So to finish this part 2 of, here’s the complete constructor of my 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.         //SimpleIoc.Default.Register<IDataService, DesignDataService>();
  9.     }
  10.     else
  11.     {
  12.         // Create run time view services and models
  13.         SimpleIoc.Default.Register<INavigationService, NavigationService>();
  14.         SimpleIoc.Default.Register<IService, SDKBroker.WinRT.Service>();
  15.         SimpleIoc.Default.Register<IMessageApi, MessageApi>();
  16.         SimpleIoc.Default.Register<IFrameworkApi, FrameworkApi>();
  17.         SimpleIoc.Default.Register<IDispatcher, Dispatcher>();
  18.         SimpleIoc.Default.Register<INetworkApi, NetworkApi>();
  19.     }
  20.  
  21.     //register views
  22.     SimpleIoc.Default.Register<IMainPage, MainPage>();
  23.     SimpleIoc.Default.Register<IVolumeDetailPage, VolumeDetailPage>();
  24.     SimpleIoc.Default.Register<ICharacterDetailPage, CharacterDetailPage>();
  25.     SimpleIoc.Default.Register<ICollectionPage, CollectionPage>();
  26.     SimpleIoc.Default.Register<IDetailPage, DetailPage>();
  27.     SimpleIoc.Default.Register<IIssueDetailPage, IssueDetailPage>();
  28.     SimpleIoc.Default.Register<ILocationDetailPage, LocationDetailPage>();
  29.     SimpleIoc.Default.Register<INewsFeedPage, NewsFeedPage>();
  30.     SimpleIoc.Default.Register<IPersonDetailPage, PersonDetailPage>();
  31.     SimpleIoc.Default.Register<IStoryArcDetailPage, StoryArcDetailPage>();
  32.     SimpleIoc.Default.Register<ITeamDetailPage, TeamDetailPage>();
  33.  
  34.     //register viewmodels
  35.     SimpleIoc.Default.Register<MainViewModel>();
  36.     SimpleIoc.Default.Register<VolumeDetailViewModel>(true);
  37.     SimpleIoc.Default.Register<CharacterDetailViewModel>(true);
  38.     SimpleIoc.Default.Register<TeamDetailViewModel>(true);
  39.     SimpleIoc.Default.Register<IssueDetailViewModel>(true);
  40.     SimpleIoc.Default.Register<SearchViewModel>();
  41.     SimpleIoc.Default.Register<DetailViewModel>(true);
  42.     SimpleIoc.Default.Register<StoryArcDetailViewModel>(true);
  43.     SimpleIoc.Default.Register<LocationDetailViewModel>(true);
  44.     SimpleIoc.Default.Register<PersonDetailViewModel>(true);
  45.     SimpleIoc.Default.Register<CollectionViewModel>();
  46.     SimpleIoc.Default.Register<NewsFeedViewModel>(true);
  47. }

It registers all my api and service layers, all my views that have an interface and all viewmodels.

Part 2 conclusion

After a rough start in Part 1 it seems that this experiment has forced me to improve my code by making me add some abstractions. This makes for easier reusable code, both on the same platform as on other platforms. The DEV branch of my app project is once again a fully functional Windows Store app that reacts and behaves exactly as the one that’s in the store right now. The next step is to refactor out the ViewModelLocator and then it should be about time to start work on the Windows Phone version. See you in part 3!


Tags:

.Net | Devices | Metro | MVVM Light | PCL | Windows 8 | WinRT | WP8

  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