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. public class ExtendedPivot : Pivot
  2. {
  3.     public static readonly DependencyProperty HeaderVisibilityProperty =
  4.         DependencyProperty.Register("HeaderVisibilityProperty", typeof (Visibility), typeof (ExtendedPivot), new PropertyMetadata(null));
  5.  
  6.     public Visibility 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. public partial class MainPage : PhoneApplicationPage
  2. {
  3.     private MainViewModel _mainViewModel;
  4.  
  5.     // Constructor
  6.     public MainPage()
  7.     {
  8.         InitializeComponent();
  9.  
  10.         _mainViewModel = new MainViewModel();
  11.  
  12.         DataContext = _mainViewModel;
  13.     }
  14.  
  15.     private void 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 | Devices | Binding | WP7 | WP8 | XAML

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

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

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

Porting a real win8 app to WP8–part 1

by Nico

A few weeks ago the first version of my Windows 8 app (finally) hit the store (download it here).  From the start I wanted to port this application to Windows Phone 8 as well but I didn’t keep that in mind when developing the app. Some time ago, the portable HttpClient was released in a beta version and to me that was the perfect time to see how useful the portable class libraries (PCL) really are.

Most of the information available on the internet on sharing code between Windows Store and Windows Phone apps have those really small basic projects, good stuff to get started, but I want to port an entire, finished project to another platform. Perfect content for some blog posts so I’ll be documenting my progress here on my blog, hopefully it will be to some use.

The app

The app is called Comic Cloud and is a continuation of my very first Windows Phone 7 app ever. It allows users to search for anything related to comic books (volumes, issues, artists, characters, locations, …) and provides a whole bunch of information on the topic. The data comes from a community driven website (think Wikipedia for comics) called ComicVine. They have a great REST API with great documentation so that was perfect. On the other hand, and this is new in the Windows 8 version, users can start tracking their own collection of comic books and keep track of which issues in their collection are already read. This data is saved on Azure by using the awesome Azure Mobile Services, authentication happens with the Microsoft Account (single sign-on). So researching and collection are the two keywords of the application. Since the API is REST based, I make extensive use of the HttpClient class to make the API calls.

Architecture

As for architecture, all libraries are Windows Store class libraries and then off course there’s the app itself, written in C# and XAML. This image shows the projects and their dependencies.

(The app was called ComicDB in its begin stages, the namespaces stayed but the app title was changed to Comic Cloud)

The solution exists of five projects, first there’s the app itself using MVVM Light, win8nl for winRT behaviors (written by Joost van Schaik), MarkedUp for analytics, Callisto for settings fly-out, the Live SDK for the User class and the Telerik RAD controls for their controls (obviously).

The Model project contains all classes, there’s the ComicVine classes (thank God for paste JSON as class…) and some classes for RSS feeds and links.

Since I want to limit the amount of data stored in my WAMS database, I only save the userID and the link to the ComicVine API for each item. For that I needed a second version of some classes, that’s what the DTO project is for.

The framework is a project that I can reuse in other projects without changing anything, all classes that are app independent. Things like the RestClient (providing generic CRUD functions), the GroupInfoList for grouped gridviews, navigationservice to navigate between pages and so on. The ComicVineHelper is an extension method that changes the casing of some object to be compatible with the way the ComicVine API works. All these classes are implementing interfaces, so that will be a big plus when I start porting.

The SDKBroker takes all the different services I use and puts them together in one big SDK that’s easy to use from the app.

The idea

So the idea was to take all those libraries, put them in PCL libraries and reference them from both the Windows Store app and the Windows Phone app. Next to that I wanted to use the portable version of MVVM Light to share my viewmodels over both projects as well. Turns out that, as usual, a good idea is stopped by technical limitations.

The problem

The problem is the difference between Windows 8 and Windows Phone, they don’t share their entire codebase. Meaning I can’t reuse all my code in a PCL. Also the Azure Mobile Services SDK has no portable version, so same problem there.

The solution is abstractions, create an interface for every class that isn’t compatible with the PCL projects and implement them in a platform specific library. The PCLs I’m using only target .net 4.5, winRT and WP8 so a lot of problems are already taken care of by not selecting WP7.X compatibility.

The road so far

I wanted to start out by replacing MVVM Light with the PCL version. This turned out to be easier said than done, the initial project was started from the MVVM Light template so I threw out the references to MVVM Light and added the PCL version through NuGet. Visual Studio went quite mad and started throwing all sorts of weird build errors, I eventually found out that the win8nl library also includes the MVVM Light assemblies and those conflicted with the PCL versions. But I needed the win8nl assembly for the eventtocommand behaviors in WinRT so that posed a big problem. Luckily there’s the winRTBehaviors assembly that contains the logic to do behaviors but it doesn’t include the actual eventtocommand one. The solution was to go to the Codeplex site of win8nl and copy the behavior classes from there and put them in my framework project. One problem solved.

The next step was to add a PCL for the Framework and SDKBroker projects, the Model was already a PCL so that one could stay as it was. The PCL libs got named ComicDB.Framework and ComicDB.SDKBroker, they contain a combination of interfaces and classes. Everything that couldn’t be made portable was abstracted into an interface and implemented in platform specific libraries called ComicDB.Framework.WinRT and ComicDB.SDKBroker.WinRT. The classes that needed abstraction were the NavigationService, Network helper, WAMS service class and Service helper. Thanks to the new portable HttpClient assembly I could copy my RestClient class to a PCL without any adjustments.

With some tinkering I got the project to build and run again and I saw that it was good. The time had come to move my ViewModels over to a PCL. I added a new PCL project called ComicDB.ViewModel (same namespace as my VMs already had) and added the portable MVVM Light version. The ViewModelLocator can’t be moved since it needs to register all the correct interface implementations into the IOC container, so I’ll have a separate Locator class for Win8 and WP8. As I started moving ViewModels I quickly ran into a navigational problem, my viewmodels have navigation logic and the pages they are navigating to aren’t known in the PCL. To solve this I’ve created an interface for every page and set that as navigational target, I don’t know if this will work but I’ll find out soon enough and put it in part 2 if this diary.

Navigational problem solved, on to the next one. Two of my viewmodels could show toast notifications, I use the notifications helper classes from MSDN to get this done but the notification classes aren’t portable (and they really don’t need to be since Windows Phone doesn’t support in-app toasts, the C4F toolkit fixes that luckily) so I created an IMessageAPI interface that has a PopToast() method. In FrameWork.WinRT it shows a build-in toast just like the app used to do.

Hey remember that we have to do everything async now and that we can call the Dispatcher to execute something on the UI thread? Not happening in a PCL… MVVM Light contains a DispatcherHelper that checks if an action needs to be executed on the UI thread and actually executes it there when needed, except in the PCL version. So IDispatcher was born.

With that done I got my project to build again and to run but it’s currently still using the old viewmodels, I expect a whole bunch of new problems when I try to change it to the PCL versions, but that will be for part 2.

What’s next

In part 2 I hope to make the app use the PCL version of the viewmodels and I’ll start working on the Windows Phone project.

Conclusion

PCL projects sound very good in theory but in reality they are a great PITA to work with. Portable HttpClient and portable MVVM Light make them useful but you’ll have to right loads of extra code, abstractions and helper classes to get to something that looks like build once run on two platforms. I could’ve given up and just rebuild everything in a separate solution for WP8 but I want to see how far I can take this and document it along the way.

That said, I have no idea when part 2 will be live, that depends on when I can gather the courage to reference the viewmodel project Smile


Tags:

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

Getting home with Windows Phone 8 and NFC

by Nico

Imagine this, you’re somewhere you’ve never been before and you need your phone to navigate you home but you need a quick getaway and don’t have time to enter the address manually. Or you’re taking the boy/girl of your dreams home after a great date and want to impress them with some technological stuff (because geeks are the new sexy). In both scenarios NFC can come to the rescue. In this article I’m going to explain how you can program an NFC tag to launch your navigation app and navigate you home. (NOTE: this has been tested on a Nokia Lumia 920 with Nokia Drive).

First, the prerequisites. We need an NFC capable Windows Phone 8 device with navigation software. We also need a blank, NDEF formatted, writable NFC tag (I got mine from RapidNFC). We’ll also need a dataconnection to fetch our coordinates (only for writing the NFC tag).

Next, the pieces of the puzzle. In this case there are three things that need to be taken care of. First we need to be able to enter an address in an app and get the longitude/latitude coordinates for that address. Second, we need to write the instruction for launching the navigations app and navigating to those coordinates to an NFC tag and third we need our phone to actually launch the app and navigate to the received coordinates. Now to make that last part work we only need to make sure we have an NFC capable phone, have NFC enabled in Settings and that we have navigational software installed.

Enough planning, let’s get to work. First the UI, I‘m going with two TextBlocks, one to enter the address and one that will show the coordinates just to see if that worked. I also need two buttons, one for fetching the coordinates and one for writing the NFC tag. Here’s the XAML

Code Snippet
  1. <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
  2.     <StackPanel>
  3.         <TextBlock Text="Address" />
  4.         <TextBox x:Name="TextBoxAddress" />
  5.                         <TextBlock Text="Coordinates" />
  6.            <TextBox x:Name="TextBoxCoordinates" />
  7.         
  8.         <StackPanel Orientation="Horizontal">
  9.             <Button Content="Get Coordinates" Click="GetCoordinatesButtonClick" />
  10.             <Button Content="Write NFC tag" Click="WriteTagButtonClick" />
  11.         </StackPanel>
  12.     </StackPanel>
  13. </Grid>

With this as the final result

How this works, we enter an address in the top TextBox and click the “Get Coordinates” button. This will use the Microsoft.Phone.Maps functionality to translate that address into coordinates, those coordinates will show up in the bottom TextBox. When we click the “Write NFC tag” button the app will wait for a writable NFC tag, once that’s detected the data will be written on it. All it takes then is a tap on the tag and the phone will take you home.

Before we dive into code we need to add some capabilities. Using the Maps namespace and using NFC requires two capabilities, double-click the WMAppManifest.xml file and select these capabilities.

This will keep us away from any UnauthorizedExceptions.

On to the code we go, we’ll start with declaring some private fields.

Code Snippet
  1. private GeoCoordinate _coordinate;
  2. private ProximityDevice _device;

After that, we go to the “Get Coordinates” button.

Code Snippet
  1. private void GetCoordinatesButtonClick(object sender, RoutedEventArgs e)
  2. {
  3.     string address = TextBoxAddress.Text.Trim();
  4.  
  5.     if (address == string.Empty)
  6.     {
  7.         MessageBox.Show("Address cannot be empty!");
  8.         return;
  9.     }
  10.  
  11.     GeocodeQuery query = new GeocodeQuery
  12.                              {
  13.                                  GeoCoordinate = new GeoCoordinate(0, 0),
  14.                                  SearchTerm = address
  15.                              };
  16.  
  17.     query.QueryCompleted += (o, args) =>
  18.                                 {
  19.                                     if (args.Result == null)
  20.                                     {
  21.                                         TextBoxCoordinates.Text = "No coordinates found";
  22.                                         return;
  23.                                     }
  24.                                     _coordinate = args.Result[0].GeoCoordinate;
  25.                                     TextBoxCoordinates.Text = string.Format("Lat: {0} / Lon: {1}",
  26.                                         args.Result[0].GeoCoordinate.Latitude.ToString(),
  27.                                         args.Result[0].GeoCoordinate.Longitude.ToString());
  28.                                 };
  29.     query.QueryAsync();
  30. }

First thing we need to do is verify if an address was actually entered in the TextBlock. When that’s verified we declare a GeocodeQuery and initialize it with a new GeoCoordinate and pass the address as a SearchTerm. When the query completes we check if there’s a result. The query should return a result of type IList<MapLocation> the first element in the list is the one we need, and from this first item we need the GeoCoordinate property, we’ll put that one in the _coordinate field. We call the QueryAsync() method on GeocodeQuery to get the result. For some reason QueryAsync returns void, meaning we can’t just await it. We need to do this the oldschool way and use the QueryCompleted event handler.

With that, the first part of our puzzle is solved. We can go from an address to a coordinate. Now we just need a way to get this coordinate and the navigation app launch instruction onto an NFC tag. Let’s have a look at what happens when the “Write NFC tag” button is clicked.

Code Snippet
  1. private void WriteTagButtonClick(object sender, RoutedEventArgs e)
  2. {
  3.     _device = ProximityDevice.GetDefault();
  4.  
  5.     if (_device == null)
  6.     {
  7.         MessageBox.Show("NFC not detected, is it disabled?");
  8.         return;
  9.     }
  10.  
  11.     TextBlockStatus.Text = "NFC detected, waiting for writable tag";
  12.  
  13.     _device.SubscribeForMessage("WriteableTag", (device, message) =>
  14.                     {
  15.                         Deployment.Current.Dispatcher.BeginInvoke(() =>
  16.                                         {
  17.                                             TextBlockStatus.Text = "writable tag detected";
  18.                                         });
  19.                         WriteTag();
  20.                     });
  21. }

There’s some NFC magic going on here. First we instantiate a ProximityDevice instance and activate the proximity provider. If, at that point, _device is null it means that the Windows Phone device either has no NFC capabilities or they are disabled in Settings > Tap & Send. If _device is not null we have successfully initialized NFC. Line 13 is a bit special. We call the SubscribeForMessage() method on the ProximityDevice. What happens is, when the NFC provider reads a tag it sends a message, we subscribe to the “WritableTag” message because it’s the only thing we can use in this case. If you want a complete list of all supported message types, have a look at MSDN.Since the subscription doesn’t live on the UI thread we need to use the Dispatcher in order to update the TextBlock that hold the status. The WriteTag() method gets called when a writable NFC tag is detected.

Code Snippet
  1. private void WriteTag()
  2. {
  3.     string uri = string.Format(@"ms-drive-to:?destination.latitude={0}&destination.longitude={1}",
  4.         _coordinate.Latitude.ToString(CultureInfo.InvariantCulture),
  5.         _coordinate.Longitude.ToString(CultureInfo.InvariantCulture));
  6.  
  7.     var writer = new DataWriter
  8.                          {
  9.                              UnicodeEncoding = UnicodeEncoding.Utf16LE
  10.                          };
  11.  
  12.     writer.WriteString(uri);
  13.  
  14.     _device.PublishBinaryMessage("WindowsUri:WriteTag", writer.DetachBuffer(), (sender, id) =>
  15.         Dispatcher.BeginInvoke(() => TextBlockStatus.Text = "Tag written"));
  16. }

This method is the piece of magic that glues all pieces together. We start by setting the Uri that will launch when the tag is tapped. “ms-drive-to” means we need whatever app is registered to the drive-to command (you can also get walking directions by using “ms-walk-to”) the rest of the string are parameters we’re passing into that app. We are passing the coordinates into the app, passing those in means that the app knows we want to navigate and where we want to go. We also need a DataWriter with Utf16LE encoding (this is the encoding needed for writing uri messages to NFC tags). We fill the buffer of the DataWriter with the uri string we’ve constructed a second ago and we publish it through the ProximityDevice as a binary message. The PublishBinaryMessage() method takes in a messagetype and an implementation of IBuffer, provided by the DataWriter in this case. In an overload the method also takes a method that fires when the publish is completed, we use this event handler to update our UI.

That’s all folks, with a bit of tinkering we’ve combined two possibilities of the Windows Phone 8 platform in a very cool, almost “magical” trick. I've got my NFC sticker in my car, impressing people wherever I go and now you can all be as cool as I am Smile you’re welcome.

To finish of, some action shots of the app.


Coordinates detected


Tapped a programmed tag


Navigation started


Tags:

NFC | .Net | Devices | WP8 | XAML

Windows Phone 8 and Fiddler

by Nico

Fiddler and the WP8 emulator

Fiddler is a great tool for capturing network traffic. I find it especially useful when I’m working with services. It sniffs out your network traffic and allows you to dig into every incoming or outgoing request. You can even create requests from inside the tool. The tool itself is free to use and can be downloaded from https://fiddler2.com/fiddler2/

So how does it work? Fiddler installs a proxy on your machine (default on port 8888). That proxy intercepts all network traffic going from and to the machine it’s installed on. That traffic gets displayed in the Fiddler UI. The proxy captures the traffic, sends it to the application and let the traffic itself pass to the original destination. This image shows the normal client – internet situation (top half) and the situation with Fiddler installed (bottom half).

Makes sense? Nothing to difficult about this. What I just explained here is the basic functionality of Fiddler. Only monitoring your local traffic. The Windows Phone 8 emulator runs as a Hyper-V virtual machine, meaning it identifies itself as a separate device on the network. But that’s not really a problem, Fiddler in al its greatness can monitor remote devices as well. Here’s how to enable it.

First, start Fiddler and go to Tools > Fiddler options. Go to tab “Connections” and check the “Allow remote computers to connect” option.

Click OK, back on the Fiddler main screen, you’ll notice a textbox underneath the list of captured requests (a black one). That’s called the QuickExec box, it can be used to set preferences. In our case we need to add a hostname to our proxy. The hostname we need to add is the one from the Hyper-V host that is running the Windows Phone emulator, your developer machine in other words. Since all traffic from the Windows Phone emulator goes through our developer machines we need to attach Fiddler to our pc. The default localhost connection won’t work so we need to attach the Fiddler proxy to the network name.

In the QuickExec box enter this command

prefs set fiddler.network.proxy.registrationhostname <your computername>

With that done, restart Fiddler and the Windows Phone emulator and behold the emulator’s traffic getting sniffed. As you can see on the screenshot below, if I use the mobile browser in the emulator to go to my blog Fiddler captures all the images, pages, scriptfiles etc. that are getting loaded. If I select one, the user agent clearly points to the Windows Phone 8 browser.

Note that it doesn’t just captures the emulator’s traffic, all the localhost traffic is still captured as well.

Keep in mind that if you close Fiddler now there’s a chance that the Windows Phone emulator won’t have network access anymore, that’s because at startup it configured the Fiddler proxy as gateway, closing Fiddler means disabling the proxy. Simply restart the emulator and it should work fine again.

This is all great stuff, but eventually we’ll run into a situation where we need to sniff network traffic but for some reason we can’t use the emulator. With Fiddler we can also sniff the network traffic from an actual Windows Phone device, provided the machine running Fiddler and the Windows Phone are connected to the same network.

Fiddler and WP8 devices

To do this, setup Fiddler the same way as we did for the emulator. When that’s done, on you Windows Phone device go to Settings > WiFi. Select the wireless network that your phone is connected to and enable the Proxy. Set the proxy url to the IP address or the hostname of the computer running Fiddler and the port to 8888.

Fire up Fiddler, fire up the mobile browser on your phone and be amazed!

If you’re decrypting HTTPS traffic you might need to install the Fiddler certificate on your phone, the browser will prompt you to install it. Before testing your app with HTTPS, try the browser first so the certificate gets installed. Do be aware that every Fiddler installation generates its own certificate (they are self-signed so you might get a security warning, in this case its perfectly safe to ignore that warning) so you might need to install a new one when you use Fiddler on another machine.

 

Conclusion

In this post we’ve talked about using Fiddler, a great tool for sniffing and decrypting network requests, with both the Windows Phone 8 emulator and Windows Phone 8 devices. It’s really easy to setup and a great asset when working or developing services.

A few remarks to end this post:

If you ever change your computer’s hostname Fiddler will stop capturing Windows Phone network. Use the prefs set fiddler.network.proxy.registrationhostname <your computername> command again in the QuickExec box with the new hostname and Fiddler will happily continue its work.

If you computer is joined to a domain that has IPSEC security setup you will need to ask the administrator to add a IPSEC Boundary Computer exception for your computer.

Happy sniffing!


Tags:

.Net | WP7 | WP8 | Devices

Stream comics from Windows 8 to other devices using PlayTo

by Nico

There are plenty of blogposts, tutorials, videos, books and many more out there that talk about searching, sharing settings and if you’re lucky even printing. But the Devices charm can be used for something way cooler than printing some pages, it can trigger the Play To contract.

The Play To contract can share media like music, video and pictures to other devices on your network, be it other Windows 8 devices or even Xbox 360 consoles. Being a comic geek I the first thing on my mind when reading about the Play To contract was “this would be awesome to stream comics from my pc to my Xbox” and so a challenge was born and accepted on the same day. An evening or two of hacking later I’m proud to say that I did it and it’s really easy, just like everything that involves charms (Microsoft really did a good job on allowing us to integrate our apps with the OS here). Most of the time putting this thing together went to building the actual comic viewer, but enough talk, let’s take a look at how it’s done. First let me show you how it looks like, we’ll start with the app itself.

Pretty empty so far, if we load a digital comic (only .cbz format supported in this demo) and select the Devices charm we get this.

That’s right! that’s Captain America himself, including Bucky. And oh yeah, the xbox shows up in the Devices charm as well. After selecting the xbox from the list of devices we get this.

And here it is playing on my TV (yes that’s a Sony, because Microsoft doesn’t build televisions yet Winking smile)

Pretty cool eh? Let’s check under the hood.

First, a digital comic mostly exists in either .cbz or .cbr format. They’re actually nothing more then a zip or a rar file (Comic Book Zip and Comic Book Rar). Since WinRT has the ZipArchive class we can support .cbz out of the box, for cbr format we would need to find a library that supports rar files but that’s outside the scope of this post.

First the XAML, the main control here is a FlipView, that allows for touch and mouse support out of the box. The FlipView is bound to a collection of bitmap images that get loaded from the digital comic. Next to the FlipView there’s also an appbar containing the load file button and a textblock that shows the connection to other devices.

   1: <common:LayoutAwarePage.BottomAppBar>
   2:     <AppBar IsOpen="True" Background="#FF1A76B6">
   3:         <StackPanel Orientation="Horizontal">
   4:             <Button Click="OpenButton_Click" Style="{StaticResource OpenFileAppBarButtonStyle}" />
   5:         </StackPanel>
   6:     </AppBar>
   7: </common:LayoutAwarePage.BottomAppBar>
   8:  
   9: <Grid Style="{StaticResource LayoutRootStyle}">
  10:     <Grid.RowDefinitions>
  11:         <RowDefinition Height="140"/>
  12:         <RowDefinition Height="*"/>
  13:     </Grid.RowDefinitions>
  14:  
  15:     <TextBlock x:Name="ConnectionText" TextWrapping="Wrap" Text="Not connected" Margin="38,18,766,571" 
  16:                Grid.Row="1" Style="{StaticResource SubheaderTextStyle}"/>
  17:  
  18:     <FlipView x:Name="FlipImage" Margin="0,3,0,0" Grid.RowSpan="2" SelectionChanged="FlipImage_NextImage">
  19:         <FlipView.ItemTemplate>
  20:             <DataTemplate>
  21:                 <Image Source="{Binding}" />
  22:             </DataTemplate>
  23:         </FlipView.ItemTemplate>
  24:     </FlipView>
  25:  
  26:     <Grid>
  27:         <Grid.ColumnDefinitions>
  28:             <ColumnDefinition Width="Auto"/>
  29:             <ColumnDefinition Width="*"/>
  30:         </Grid.ColumnDefinitions>
  31:         <Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" 
  32:                 Style="{StaticResource BackButtonStyle}"/>
  33:         <TextBlock x:Name="pageTitle" Grid.Column="1" Text="{StaticResource AppName}" 
  34:                    Style="{StaticResource PageHeaderTextStyle}"/>
  35:     </Grid>
  36: </Grid>

The FlipView template is just a simple Image control, nothing special in the XAML, the magic is in the code behind.

First some fields that we’ll need later on

   1: private List<BitmapImage> _pages;
   2: private bool _isConnected;
   3: private Image _current;

We’re going to take a look at how to load the cbz file first, I’ll go over this quickly as the main focus of this post is the PlayTo contract.

   1: private async void OpenButton_Click(object sender, RoutedEventArgs e)
   2: {
   3:     _pages = new List<BitmapImage>();
   4:  
   5:     _pages = await OpenZip();
   6:  
   7:     if (_pages.Count > 0)
   8:         FlipImage.ItemsSource = _pages;
   9: }

All we do in the button’s eventhandler is initializing the field that will hold all the pages, call the function that will load the file and if it contains any items it will set the FlipView’s itemssource to that list. Next up: the function to load the comic.

   1: async Task<List<BitmapImage>> OpenZip()
   2: {
   3:     FileOpenPicker openPicker = new FileOpenPicker();
   4:     List<BitmapImage> comic = new List<BitmapImage>();
   5:  
   6:     openPicker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
   7:     openPicker.FileTypeFilter.Add(".cbz");
   8:  
   9:     var storageFile = await openPicker.PickSingleFileAsync();
  10:     // Create stream for compressed files in memory
  11:     using (MemoryStream zipMemoryStream = new MemoryStream())
  12:     {
  13:         using (IRandomAccessStream zipStream = await storageFile.OpenAsync(FileAccessMode.Read))
  14:         {
  15:             // Read compressed data from file to memory stream
  16:             using (Stream instream = zipStream.AsStreamForRead())
  17:             {
  18:                 byte[] buffer = new byte[1024];
  19:                 while (instream.Read(buffer, 0, buffer.Length) > 0)
  20:                 {
  21:                     zipMemoryStream.Write(buffer, 0, buffer.Length);
  22:                 }
  23:             }
  24:         }
  25:  
  26:  
  27:         // Create zip archive to access compressed files in memory stream
  28:         using (ZipArchive zipArchive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Read))
  29:         {
  30:             // For each compressed file...
  31:             foreach (ZipArchiveEntry item in zipArchive.Entries)
  32:             {
  33:                 if (item.Name.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase))
  34:                 {
  35:                     byte[] imageInBytes;
  36:  
  37:                     using (MemoryStream ms = new MemoryStream())
  38:                     {
  39:                         var stream = item.Open();
  40:                         stream.CopyTo(ms);
  41:                         imageInBytes = ms.ToArray();
  42:                     }
  43:  
  44:                     BitmapImage bImg = new BitmapImage();
  45:                     await bImg.SetSourceAsync(new RandomStream(imageInBytes));
  46:  
  47:                     comic.Add(bImg);
  48:                 }
  49:             }
  50:         }
  51:     }
  52:  
  53:     return comic;
  54: }

We start by initializing the FileOpenPicker, allowing our user to select the comic he/she wants to read. We add a suggested location where the FileOpenPicker should start and add the filetypes it should look for. The PickFileAsync method shows the actual filepicker to the user, the user selects the cbz file he wants and it gets loaded into the storageFile variable. The file gets read in as an IRandomAccessStream. We need that stream to create a ZipArchive instance. Once we have that we can loop through all files in that zip archive. Each .jpg file in that zip archive gets read into a byte array that we then convert into a bitmap by using RandomStream, an implementation of IRandomAccessStream (if you want to see the implementation, the project is attached to this post at the bottom). The bitmap image then gets added to the list. When they’re all done the list gets returned to the caller.

That’s it for loading the comic, let’s take a look at the sharing to other devices in your network.

We need to initialize the PlayTo contract, I’ll be doing this from the constructor

   1: public MainPage()
   2: {
   3:     InitializeComponent();
   4:  
   5:     var playToManager = PlayToManager.GetForCurrentView();
   6:     playToManager.SourceRequested += PlayToManagerOnSourceRequested;
   7:     playToManager.SourceSelected += PlayToManagerOnSourceSelected;
   8: }

PlayToManager is the class that we need, we get this for free from the WinRT framework. The GetForCurrentView() method returns an instance of the PlayToManager class bound to this page. Once we have the instance we attach an eventhandler to the SourceRequested and the SourceSelected events. The SourceRequested event will fire as soon as the user hits the Devices charm, this is where we’ll prepare the first media element for streaming. The SourceSelected event fires when the user selects a source, obviously.

   1: private async void PlayToManagerOnSourceRequested(PlayToManager sender, PlayToSourceRequestedEventArgs args)
   2: {
   3:     var deferral = args.SourceRequest.GetDeferral();
   4:  
   5:     await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
   6:         {
   7:             var firstImage = GetChildren(FlipImage).First();
   8:  
   9:             // Provide Play To with the first image to stream.
  10:             args.SourceRequest.SetSource(firstImage.PlayToSource);
  11:             _current = firstImage;
  12:             deferral.Complete();
  13:         });
  14:  
  15: }

The OnSourceRequested eventhandler needs to be marked as async. First we get the deferral, then we need to run some async code, Dispatcher.RunAsync is the same as calling an async method with await on this line. The PlayTo contract works with certain XAML controls. In our case we need the Image control, that’s why we’ve set the itemtemplate of the FlipView to be an Image. We’ll take a look at the GetChildren() method in a minute, for now just know that it returns a list of all Image controls inside the FlipView. We take the first element in the returned list and that’s the element that we’ll stream to the device. The arguments have a property of type PlayToSourceRequest, that one has a SetSource function that takes in a PlayToSource object and that’s a property of the Image control. We set the current image to the _current field and mark the deferral as complete.

Phew that was quite some work. Don’t worry, the hard part is over (yes this was really the hard part). Now a quick look at that GetChildren() function.

   1: private List<Image> GetChildren(DependencyObject parent)
   2: {
   3:     var list = new List<Image>();
   4:  
   5:     for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
   6:     {
   7:         var child = VisualTreeHelper.GetChild(parent, i);
   8:         var item = child as Image;
   9:         if (item != null)
  10:             list.Add(item);
  11:  
  12:         list.AddRange(GetChildren(child));
  13:     }
  14:  
  15:     return list;
  16: }

The function takes in a DependencyObject and starts walking through its visual tree. We try to cast each item as an Image, if that cast fails the variable will contain null, a quick check there and if it isn’t null we add it to the list which we then return.

The OnSourceSelected is only used to set the name of the selected source to the textblock

   1: private async void PlayToManagerOnSourceSelected(PlayToManager sender, PlayToSourceSelectedEventArgs args)
   2: {
   3:     _isConnected = true;
   4:  
   5:     await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
   6:         ConnectionText.Text = string.Format("Connected to {0}", args.FriendlyName));
   7: }

And that’s enough to stream the first image, when you run this code and select the Devices charm the first page of the comic should show up on your device. All there’s left now is to go back and forward in the comic. In the app itself this already works, the FlipView takes care of navigating between the pages. Before we start developing this we need to make a small halt and take a look at how the FlipView actually works. First thought in my head was “okay this is easy, I just get all the image controls in the FlipView and I’m golden”. That was a big nono. The itemspanel of a FlipView is actually a VirtualizingStackPanel, meaning that at any given time there are maximum three Image controls inside the FlipView, usually previous-current-next. As soon as we navigate to another page the FlipView automatically loads in the next item in line. This can easily be seen by using a handy tool called XamlSpy. XamlSpy allows us to view the entire visual tree of any XAML based application. When we view the default visual tree of a FlipView after loading a comic we get this.

As you can see, we only have three FlipViewItems here. When we change the FlipView’s paneltemplate to this

   1: <FlipView x:Name="FlipImage" Margin="0,3,0,0" Grid.RowSpan="2" SelectionChanged="FlipImage_NextImage">
   2:     <FlipView.ItemsPanel>
   3:         <ItemsPanelTemplate>
   4:             <StackPanel />
   5:         </ItemsPanelTemplate>
   6:     </FlipView.ItemsPanel>
   7:     <FlipView.ItemTemplate>
   8:         <DataTemplate>
   9:             <Image Source="{Binding}" />
  10:         </DataTemplate>
  11:     </FlipView.ItemTemplate>
  12: </FlipView>

and we load the same comic in XamlSpy we get this result

Quite the difference I would say. The VirtualizingStackPanel is lighter on memory usage, since some comics can be quite large we’ll stick to the default template.

Now that we have that cleared out, let’s take a look at what happens when we browse to the next page of the comic.

   1: private async void FlipImage_NextImage(object sender, SelectionChangedEventArgs e)
   2: {
   3:     if (!_isConnected) return;
   4:  
   5:     await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
   6:         {
   7:             var current = GetChildren(FlipImage)[1];
   8:  
   9:             _current.PlayToSource.Next = current.PlayToSource;
  10:             _current.PlayToSource.PlayNext();
  11:             _current = current;
  12:         });
  13: }

First, this code does not need to be executed when we’re not connected to any device, if we are we need to run the next block of code asynchronously. First the code fetches all the available Image controls inside the FlipView, we save a reference to the middle one because that one is the one currently shown in the FlipView. The field _current contains the image currently shown on the external device, we need to set that field’s PlayToSource.Next property. That property always needs to be set on the current image before the PlayNext() method is called. Once that’s set we call the aforementioned PlayNext() method. That method will sent the control that is set to the PlayToSource.Next property to the connected device. To end we set the image control that was just send to the device to the _current field so that it can be called upon on the next run.

In this post I have shown how you can share media content from your Windows Store application to an external device like the Xbox 360. The project used in this post can be downloaded from my SkyDrive


Tags:

.Net | Devices | Metro | WinRT | Windows 8 | XAML

XNA Lunch game update

by Nico

So I’ve already missed my first blog appointment about the Windows Phone game that I’m developing during my lunch brakes. Not a good start, but I’m taking two weeks off work so I do have a valid excuse Glimlach

Last week I worked 3 hours on the game in total, my vacation started on Thursday with the app-a-thon. In those three hours I reworked the control scheme. Previously the character was moved using a virtual, on-screen thumbstick. That worked great but on a device with such small screen estate and my huge thumbs there wasn’t much left to see. So I reworked that into a point and click system, tap on the screen and the character will move to the position of the tap. A side effect of this new system is that some enemy movement bug got fixed automagically, that was a rather nice surprise.

Next to the control scheme I made some progress on the collision detection system, since my level engine is a tile based layered engine it was quite easy to do. I’ll probably dedicate a separate post on the collision detection system.

All in all good progress with little time. The project will now be shelved until the end of June, the day my vacation ends is the day I’ll pick the game back up. So that’ll be two weeks without updates.

Keep an eye on Twitter for upcoming updates and see you in two weeks!

     


Tags:

.Net | WP7 | XNA | Metro | Devices

slides and demo for my WiPhug talk

by Nico

Yesterday I did a talk in the Belgian Windows Phone User Group about beginning XNA development. It was the first time I did a talk in my own user group and I had a great time.

I also learned a very valuable lesson: don't name your Autohotkey snippets the same as your classes. It was quite the hilarious moment when I entered the class name in the "Add File" dialog and hit the Enter key.

Besides that small setback everything went great. The slidedeck and demo (shooting iphones down with a pink magenta Lumia) are zipped up and can be found here.


Tags:

.Net | Devices | WP7 | XNA

  Log in

About the author

Hi,

My name is Nico, I’m an MCP living in Belgium.
I’m currently employed as a consultant in the Mobile Solution Center at RealDolmen, one of Belgium’s leading IT single source providers, where I focus on Windows Phone and Windows 8 development.

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.

This blog will be about Windows Phone 7, C#, XNA , WPF, Silverlight, and much more!

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

 

 

MeetLogo

 

MVBLogo

mybook

 

mybook

 

Month List