26 December 2012

Handling Windows Phone 8 NFC startup events using the MVVMLight Messenger

wp_ss_20121226_0002As regular readers of this blog know, I am currently playing around with NFC on Windows Phone 8. I peeked a little in the Bluetooth app to app sample at MSDN to understand how to find a ‘peer’. A peer is defined as the same app, installed on a different phone. So basically you go around installing the app on two phones, start it on phone 1, make sure it calls PeerFinder.Start(), tap the phones together and presto - the popup as displayed in the image on the right appears. If you check ‘open app’ – or whatever it shows in the language you have selected – the app is started on the second phone as well.

You can distinguish between an app being started by itself, or with the “open app” button by overriding the OnNavigatedTo method from the app’s main startup page. If the app is all started up by itself, the NavigationEventArgs.Uri just contains the name of the main page, for instance “MainPage.xaml”. But if it is started by an NFC event, the Uri ends with the following rather funny long string:

ms_nfp_launchargs=Windows.Networking.Proximity.PeerFinder:StreamSocket

Annoyingly, the OnNavigatedTo event is only available inside the page’s code. If you want to handle this the MVVM way, you want this to be taken care of by a view model or a model, not by the page’s code behind.

I have gone the following route. First, I define a little extension method that easily helps me to determine if the app was initiated by the user or by an NFC event:

using System.Windows.Navigation;

namespace Wp7nl.Devices
{
  public static class NavigationEventArgsExtensions
  {
    public static bool IsStartedByNfcRequest(this NavigationEventArgs e)
    {
      var isStartedByNfcRequest = false;
      if (e.Uri != null)
      {
        isStartedByNfcRequest = 
          e.Uri.ToString()
          .Contains("ms_nfp_launchargs=Windows.Networking.Proximity.PeerFinder:StreamSocket");
      }
      return isStartedByNfcRequest;
    }
  }
}

And as I don’t like to pass bare events around, I make a little wrapper class to use as a message:

using System.Windows.Navigation;
using Wp7nl.Devices;

namespace PullTheRope.Logic.Messages
{
  public class NavigationMessage
  {
    public NavigationEventArgs NavigationEvent { get; set; }

    public bool IsStartedByNfcRequest
    {
      get 
      { 
        return NavigationEvent != null && NavigationEvent.IsStartedByNfcRequest();
      }
    }
  }
}

And it contains a convenient shortcut method as well. Then the only thing you have to do is indeed override the OnNavigatedTo method, like this:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
  base.OnNavigatedTo(e);
  Messenger.Default.Send(new NavigationMessage {NavigationEvent = e});
}

This is the only ‘breaking’ of the purist's MVVM approach – but as the event is nowhere else available, it’s also the only way to get it done. Sometimes you have to take the pragmatic approach. Anyway, somewhere in your model or view model you define which method should be called when the message is received

Messenger.Default.Register<NavigationMessage>(this, ProcessNavigationMessage);

a method to trap it

private void ProcessNavigationMessage(NavigationMessage message)
{
  // whatever – we are back in MVVM territory
}

and I trust you can take it from there ;-) .

Be aware the events generated are generated outside the GUI thread, so if you try to data bind properties changed from the event method, you might run into cross thread access errors. Deployment.Current.Dispatcher.BeginInvoke is your friend, then.

17 December 2012

On blogging, sharing and commenting

This is not about code, but about something a fellow developer and blogger told me, which made me quite sad. It’s a kind of personal rant, so feel free to skip it if you are looking for code.

In 2007, after a frustrating search on the internet for a complete and working code sample for whatever it was, I was quite pissed off. And I decided “well if apparently people are too lazy or too much ‘look at me’ superior to post complete and working samples, I will start doing so myself”. I also could have gone to the blogs I visited posting comments like “you moron, this code is incomplete and/or wrong” or “why don’t you stop coding/blogging the cr*p you post is useless”. While technically I would have been right, I don’t think it would have helped me solve my problems. Starting blogging myself did not help me solve that problems either, but at least I had a place where I could dump my own solutions for later reference. Very handy. Apparently other people liked it too.

I was lucky enough to post a few good articles, and a few very dumb ones too, but those were met with “hey, that’s obsolete”, “hey, this is a better solution” or “I think you are missing a few steps” – with links and information. I either did take the articles down, or reworked them with the new information. I was lucky enough not to get lambasted, flamed or receive abusive comments or mails – no, my baby steps were encouraged by a few people – mostly MVPs by the way – who kind of nudged me along the rocky path of the beginning blogger.

That encouragement made me go on, becoming confident enough so that when the occasional abusive comment arrived, I was able to ignore the wording of the comment and fix the error, or challenge the commenter: “so if you are such a know-it-all, why don’t you blog about it - why do you leave me stumbling in the dark making stupid avoidable errors?”.

I recently talked to the beginning blogger I mentioned before, who was severely flamed in the beginning of his ‘career’, and he almost quit blogging of that. The wording I use in the second paragraph are more or less quotes of what he received.

This is really very counterproductive behavior. If you are someone who likes to demonstrate his/her knowledge on someone else’s blog by making demeaning remarks – realize what you are effectively doing is extinguishing enthusiasm that may have grown into the creation of a vast information resource. You are killing creativity, stomping out the sharing flame, making one of the very few willing to take time to share knowledge retreat into his/her shell, maybe never to come back again.

The very short version:

Flaming other people’s blog has never led to more examples and information. If you want more and better examples: stimulate and encourage where you can, correct if you feel you must, and try to behave like a civilized human being.

And above all, start blogging yourself. Don’t be a prick – share. Use your knowledge to improve people, not to tear them down. That’s community. That’s how it works.

Thank you.

16 December 2012

Preventing high speed socket communication on Windows Phone 8 going south when using async/await

Currently I am working on a Windows Phone 8 action game in which you can fight a kind of duel. This involves pairing the phones via NFC and then obtaining a socket trough which the phones can exchange game information. Liking to steal from examples myself (why do you think I name my blog this way, eh?) I stole code from the Bluetooth app to app sample at MSDN. Now this is a great sample but it has one kind of problem for me.

I’ll skip the pairing, the obtaining of the socket and the definition of the data reader – that’s all documented in the MSDN sample. The method to send a message to the opponent was, in condensed form:

public async void SendMessage(string message)
{
  if (dataWriter == null)
  {
    dataWriter = new DataWriter(socket.OutputStream);
  }

  dataWriter.WriteInt32(message.Length);
  await dataWriter.StoreAsync();

  dataWriter.WriteString(message);
  await dataWriter.StoreAsync();
}

while at the same time both opponenents where listening using a simple method like

public async Task GetMessage()
{
  if (dataReader == null) dataReader = new DataReader(socket.InputStream);
  await dataReader.LoadAsync(4);
  var messageLen = (uint)dataReader.ReadInt32();
  Debug.WriteLine(messageLen);

  await dataReader.LoadAsync(messageLen);
  var message = dataReader.ReadString(messageLen);
  Debug.WriteLine(message);
  return message;
}

From the debug statements in this code you can see things weren’t exactly working as planned. Now the way this is supposed to work is as follows: as the opponent sends a message using SendMessage, the other phone is receiving a message via the socket in GetMessage. The first four bytes contain an unsigned integer containing the length of the rest of the message – which is supposed to be a string.

I noticed that while things went off to a good start, sooner or later one of the two phones would stop receiving messages or both games crashed simultaneously. I got all kind of null value errors, index out of range and whatnot. When I started debugging, I found out that while the app on phone 1 said it sent a 3-character string, the receiving app on phone 2 sometimes got a huge number for the message length, that obviously wasn’t sent, it read past the end of the stream – crash.

The MSDN sample works fine, as long as it is used for the purpose it was written, i.e. sending out (chat) messages at a kind of sedate pace – not for sending a lot of events per second to keep a game in sync. The essence of a stream is that it’s a stream indeed – things have to be written and read in the right order. For what happened of course was a race condition between two or more events in a short timeframe. The first event wrote the message length, the second event as well, then possibly a third, before the first one came to writing the actual message, and whatever arrived on the other phone was a garbled jumble of bytes that did exactly reflect what happened on the sending phone, but wasn’t the orderly message length – message payload stream the other phone expected.

The way I solved it – in a ‘there-I-fixed-it’ kind of way – was to use a lock on the write code so at least stuff went in the stream in the order the other phone was expecting it:

public async void SendMessage(string message)
{
  lock (this)
  {
    if (dataWriter == null)
    {
      dataWriter = new DataWriter(socket.OutputStream);
    }

    dataWriter.WriteInt32(message.Length);
    dataWriter.StoreAsync();

    dataWriter.WriteString(message);
    dataWriter.StoreAsync();
  }
}

Note you have to remove the “await” before the StoreAsync methods as those are not allowed within a lock. This method makes sure one message – and the whole message – is written on the stream and nothing comes in between.

Update – the first version of this posting contained a small error – which has been graciously pointed out to me by a few readers (see comments section). Also, I’ve been pointed to an article by Scott Hanselman about a similar subject. I’ve tried using the AsyncLock by Stephen Toub he describes but found out that although it works very good and my game does become a bit more fluid, the lag in getting messages across is a lot higher. Net effect: while the game runs more smoothly on both phones, the game state actually gets out of sync very fast, making the game unplayable. Apparently the AsyncLock approach doesn’t work for high speed continuous message exchange, so for now I’ll stick to the approach I described above.

20 November 2012

Passing event arguments to the WinRT EventToCommandBehavior

This week my fellow MVP Scott Lovegrove contacted me and asked if and how he could pass the result of an event to my WinRT EventToCommandBehavior and/or EventToBoundCommandBehavior. I replied this was currently not supported, but that would not be hard to make. He acknowledged that, and asked if he could mail some code. Since I am not very possessive of ‘my’ libraries, and am a lazy as any programmer should be, I responded with giving him developer access to Win8nl. He actually took up the challenge, and submitted the code.

Both EventToCommandBehavior and EventToBoundCommandBehavior now sport an extra property:

public bool PassEventArgsToCommand { get; set; }

If you set this property to true and don’t use the CommandParameter property, the method firing the command will actually pass the captured event to the model. How this works, is pretty simple to see in EventToBoundCommandBehavior:

private void FireCommand(RoutedEventArgs routedEventArgs)
{
  if (Command != null && Command.CanExecute(CommandParameter))
  {
    if (PassEventArgsToCommand && CommandParameter == null)
    {
      Command.Execute(routedEventArgs);
    }
    else
    {
      Command.Execute(CommandParameter);
    }
  }
}

Red shows the additions. Usage of course is pretty simple:

<TextBlock Text="TextBlock" FontSize="48">
  <WinRtBehaviors:Interaction.Behaviors>
    <Behaviors:EventToBoundCommandBehavior Event="Tapped" 
      Command="{Binding TestCommand}" 
      PassEventArgsToCommand="true"/>
  </WinRtBehaviors:Interaction.Behaviors>
</TextBlock>

And then you have to define a command TestCommand like this in your model:

public ICommand TestCommand
{
  get
  {
    return new RelayCommand<TappedRoutedEventArgs>(
      (p) =>
        {
           Debug.WriteLine(p.PointerDeviceType);
        });
  }
}

This will write '”Mouse”, “Touch” or “Pen” in your output window, depending on what you use to tap. Of course this is not a very useful application of this technique, but it proves the point. If you don’t use PassEventArgsToCommand both behaviors will work as before.

Now as an architect I am not too fond of this technique, because it introduces user-interface related objects into the view model – I get a bit restless when I see something like “using Windows.UI.Xaml.Input” on top of a view model class. Be careful when you use this. On the other hand, a holier-than-thou attitude ain’t gonna help getting Window 8 apps shipped and so if this will help people, I am more than fine with that.;-)

Scott tells me this code is derived from Laurent Bugnion’s original code – I did not check, but I am going to take his word for it. At the time of this writing it’s part of Win8nl 1.0.6 and already available as Nuget package. Now I only have the problem that not every line of code comes from the Netherlands, so maybe I should indeed rename this package to Win8eu ;-)

As (almost) always, a demo solution can be found here

17 November 2012

Reactive Extensions in Windows Phone 8 and the 2001 submission error

You can read the whole story if you like reading, but this whole blog post comes down to one piece of advice:

If you value your sanity, do not, under any circumstances, pull in Reactive Extensions from NuGet into a Windows Phone 8 application. Use the built-in Microsoft.Phone.Reactive.dll instead. 

Those who follow me on twitter may have seen a few tweets pass by over problems I had with the Windows Phone 8 version of my app Map Mania. The submission went OK the first time, but the test team found two bugs – bugs that were also there in previous versions, but apparently they have ramped up the quality bar again. I can only applaud that, even if I got bitten by it myself, because the test report was comprehensive and showed someone actually understood or had read into some issues that may arise when using WMS services – and by doing so, succeeded in crashing my app.

Anyway, I fixed the app, resubmitted, and then the trouble started. Although the Store Test kit showed no errors, and submission went fine showing only validated XAP’s – after a few minutes I got an e-mail from the Windows Phone dev center:

Windows Phone Dev Center app submission

We weren't able to process the app submission for Map Mania.

Unfortunately, something happened with your Windows Phone app submission. Check the status of the submission in your app list at https://dev.windowsphone.com/applicationlist. If the problem persists, contact support for assistance.

When I looked at the submission it said I had a “2001 error” with a helpful link, that leads you to a table in which it says:

There are duplicate files in AppManifest.xaml. Remove one of the files and then try again.

If rebuilding your XAP doesn't solve this problem, you may have to manually remove any duplicate files from the AppManifest.xaml in your XAP file. To rebuild your app, see Rebuilding your project in Visual Studio.

My friends, I have rebuilt the app till my fingers bled, cleaned the solution, then removed all the binaries manually, to no avail. Then I opened up the XAP to look for duplicate assemblies – there weren’t any duplicates; I scanned the AppManifest.xaml till I saw cross-eyed and didn’t find any duplicate entries there either - and after the 10th or so submit followed by automatic mail error within five minutes I gave up and indeed contacted Support.

I won’t go into full detail, but I think it’s fair to say this problem wasn’t easy to solve and Support struggled as much with it as I did. Quite some mails went back and forth, and the 9 hour time zone difference didn’t exactly work favorably for a quick resolve. It wasn’t until our Dutch DPE Matthijs Hoekstra, who I think now owe not only my sanity but possibly also my soul ;-), queried his sources and got back that a post-processing error apparently was being caused by System.Reactive.Core.dll and I was recommended to use Microsoft.Phone.Reactive.dll instead if possible.

I finally had a possible smoking gun - my own port of the #wp7nl library pulls in Reactive extensions from Nuget. So I removed the dependency from the library package, made a new local build, installed that into the app, compiled, uploaded and submitted, waiting for the inevitable dreaded 2001 error mail to pop up. Over an hour later, the only mail I got was from outlook.com reminding me of a birthday and the app status at the moment of this writing says “Status: In signing stage". Hallelujah!

Now I don’t understand why submission went OK the first time and not the second time around. But I am very glad the issue is resolved. If you use my library, please remove the references it makes to the external reactive stuff manually or wait for me to publish the version that will do without. It will be out soon, I can tell you that.

Update: #wp7nl was updated within a few hours of this post. If you use the Windows Phone 8 version, please update to 3.0.1. Should you experience problems with missing assemblies, make a manual reference to Microsoft.Phone.Reactive.dll to the projects that use wp7nl. And please remove any reference to Rx* should they linger along.

14 November 2012

A WinRT behavior to mimic EventToCommand (take 2)

(Updated with sample code January 19 2013)

Some time ago I posted a WinRT behavior to mimic EventToCommand. This behavior cunningly looked for the command name in the DataContext, but it occurred to me (and some blog post commenters as well) that it actually might be more logical skip all that skullduggery and let the developer bind to a command in stead of letting her/him provide its name as string and then go look for it.

Anyway, not wanting to break compatibility I added a new behavior to my win8nl library on CodePlex, very originally called EventToBoundCommandBehavior.

It’s working is very similar to the original EventToCommandBehavior. There are two notable differences:

  • The Command property is now no longer of type string but ICommand
  • The FireCommand method is now very simple:
private void FireCommand()
{
  if (Command != null && Command.CanExecute(CommandParameter))
  {
    Command.Execute(CommandParameter);
  }
}

Which goes to show that you can be too clever.

If you want to replace the original behavior for the new one – say, you used it like this

<TextBlock Text="TextBlock" FontSize="48">
  <WinRtBehaviors:Interaction.Behaviors>
    <Behaviors:EventToCommandBehavior Event="Tapped" 
      Command="TestCommand" 
      CommandParameter="{Binding TestProperty, Mode=TwoWay}"/>
  </WinRtBehaviors:Interaction.Behaviors>
</TextBlock>

Just go to the places marked red/underlined:

<TextBlock Text="TextBlock" FontSize="48">
  <WinRtBehaviors:Interaction.Behaviors>
    <Behaviors:EventToBoundCommandBehavior Event="Tapped" 
      Command="{Binding TestCommand}" 
      CommandParameter="{Binding TestProperty, Mode=TwoWay}"/>
  </WinRtBehaviors:Interaction.Behaviors>
</TextBlock>

Those who want to see the full source code of the new (and largely simplified) behavior can do so at http://win8nl.codeplex.com/SourceControl/changeset/view/20896#395786

Update: I’ve added some more sample code as a lot of people seem to struggle with the correct use of this behavior. Lots of time I get program problems like this: “I have a list in my view model and a command yet my command is not fired when then I tap the item”. The view model usually contains these properties:

public ObservableCollection Phones { get; set; }

public ICommand TappedCommand
{
  // code omitted
}

and the XAML is like this:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" 
  DataContext="{StaticResource DemoViewModel}">

  <GridView ItemsSource="{Binding Phones}" SelectionMode="None" 
     IsTapEnabled="True">
    <GridView.ItemTemplate>
      <DataTemplate>
        <Grid Width="350">
          <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
          </Grid.ColumnDefinitions>
          <WinRtBehaviors:Interaction.Behaviors>
            <Behaviors:EventToBoundCommandBehavior 
              Command="{Binding TappedCommand}" 
              CommandParameter="{Binding}" Event="Tapped" />
          </WinRtBehaviors:Interaction.Behaviors>

          <TextBlock Text="{Binding Brand}"/>
          <TextBlock Text="{Binding Type}" Grid.Column="1"/>
        </Grid>
      </DataTemplate>
    </GridView.ItemTemplate>
  </GridView>
</Grid>

I this case, the programmer has lost track of what’s the exact data context. Happens all the time, even to me. I’ve used colors to depict the data context changes.

  • In the black code, DemoViewModel is the data context
  • In the red code, the ObserservableCollection Phones is the data context
  • In the blue code, a single Phone is the context.

So what this code tries to do is to call a command TappedCommand on class Phone in stead of DemoViewModel.So either the command needs to be in “Phone”, or the behavior’s binding must be updated like this:

<WinRtBehaviors:Interaction.Behaviors>
  <Behaviors:EventToBoundCommandBehavior 
    Command="{Binding TappedCommand, Source={StaticResource DemoViewModel}}" 
    CommandParameter="{Binding}" Event="Tapped" />
</WinRtBehaviors:Interaction.Behaviors>

Full working example can be found here.

30 October 2012

Data binding shapes to the new Windows Phone 8 Map control (and more)

A little history

When I accepted the invitation from MADNbe to talk about Maps and MVVM on September 20 early in the summer (or what was supposed to be the summer) of 2012 the actual release date for the Windows Phone SDK 8.0 was still a mystery. As it gradually became clear the SDK would not be available at the date my talk was scheduled, I devised a plan B and in stead talked about Windows Phone 7 mapping and how to port this code and knowledge to Windows 8. I also wrote a blog post I wrote about it. Now the funny thing is - the Windows Phone 8 mapping control and the Windows 8 Bing Maps control show some remarkable similarities. So if you read this article and think “Huh? I’ve read this before” that’s entirely possible! 

Hello 8 WorldSo world in general, and Belgium in particular, meet the new Hello World, Windows Phone 8 style!

Windows Phone 7 map binding recap

Not going to happen - I am not going to repeat myself for the sake of content ;-). In the the Windows 8 article I give a short recap of how you can bind to a Windows Phone 7 map, using templates. I’d suggest you read that if you haven’t done so already ;-). By the way, the sample solution contained with this project is mostly the same as the sample Windows Phone 7 application I use in my talk. I upgraded to Windows Phone but did not even bother to change the libraries I used. (like MVVMLight, Phone7.Fx or my own wp7nl library). That’s still Windows Phone 7 code and you call that code from Windows Phone 8 without any problem. Very soon I hope to publish updates for the libraries specific to the platform, and you will see them appearing in your NuGet package manager. The only thing you have to keep in mind is that the app no longer runs in quirks mode once you upgraded to Windows Phone 8. That means – if your library code does something funky that has a different behavior under Windows Phone 8, the platform is not going to help you keep that funky behavior  - unlike when you run a (real) Windows Phone 7 app on it.

Data binding and the new map control

Without cheering overly loud for ‘my’ home team, I actually think the Windows Phone mapping team actually has done a better job on this part than their Windows 8 brethren. That’s actually not so very hard, as the Windows 8 Bing Maps control does not support data binding at all. The Windows Phone 8 control actually (still) supports the binding of Center and ZoomLevel, as well as the new properties CartographicMode, LandMarksEnabled, Heading and Pitch, – “Heading” being the direction of the top of the map, default 0, being North – and Pitch the viewing angle of the map (normally zero, or ‘straight from above’). And probably some more I haven’t used yet.

But as far as drawing shapes on the maps are concerned, we are in the same boat as in Windows 8:

  • The shapes the control draws cannot be templated. They are apparently just projections of something native (as is the map itself).
  • There are only two kinds of shapes: MapPolygon and MapPolyline, both descending from MapElement (as opposed to MapShape in Windows 8), which in turn descends from DependencyObject – so I can use the same trick again – storing data in attached dependency properties.

To solve this, I use the same approach as I did in Windows 8: apply behaviors. Only that’s a lot easier now because unlike Windows 8, Windows Phone 8 supports behaviors out of the box.

Introducing MapShapeDrawBehavior for Windows Phone 8

This behavior is, just like it’s Windows 8 brother, called MapShapeDrawBehavior. It’s use is quite similar:

<Maps:Map x:Name="map" CartographicMode="Road">
  <i:Interaction.Behaviors>
    <MapBinding:MapShapeDrawBehavior LayerName="Roadblocks" 
       ItemsSource="{Binding RoadBlocks}" 
       PathPropertyName="Geometry">
      <MapBinding:MapShapeDrawBehavior.EventToCommandMappers>
        <MapBinding:EventToCommandMapper EventName="Tap" 
                                         CommandName="SelectCommand"/>
      </MapBinding:MapShapeDrawBehavior.EventToCommandMappers>
      <MapBinding:MapShapeDrawBehavior.ShapeDrawer>
        <MapBinding:MapPolylineDrawer Color="Green" Width="10"/>
      </MapBinding:MapShapeDrawBehavior.ShapeDrawer>
    </MapBinding:MapShapeDrawBehavior>
  </i:Interaction.Behaviors>
</Maps:Map>

The only difference, in fact, with the Windows 8 behavior is that there is not a TapCommand property but an EventMapper collection. That is because unlike the Windows 8 map shapes, Windows Phone 8 shapes don’t support events at all. These are events of the map. There aren’t any layers for shapes too – there is just a MapElements collection that you can add shapes to.

So for every category of objects you define a behavior; in this case the road blocks (the green line on the app sceenshot above). This translates conceptually to a ‘layer’. Then you need to define three things per layer:

  • Which property in the item view model contains the Path – this is the terminology for a MapElement collection of points. This is of type GeoCoordinateCollection.
  • A drawer. A drawer is a concept I made up myself. It’s a class that creates a shape from a collection of points contained in a GeoCoordinateCollection. It’s my way to make something that’s not templatable more or less configurable and the idea behind is exactly the same as for Windows 8.
  • What command in the item view model (in this case, a RoadBlockViewModel) must be called when a GestureEvent is called on the map. This can be either Tap or DoubleTap. You do this by adding an EventToCommandMapper to the EventToCommandMappers list.

          This behavior comes, just like it’s Windows 8 brother,  the three out-of-the box standard drawers: MapPolylineDrawer, MapPolygonDrawer, and MapStarDrawer. The last one draws a configurable star shaped polygon around a point – since map shapes cannot be points by themselves. A drawer needs only to implement one method:

          public override MapElement CreateShape(object viewModel, LocationCollection path)

          The basic drawers don’t do anything with the view model: they just take the settings from XAML. You can write your own if you want for instance return a shape of a different color based upon view model values. Thematic mapping again, just like I said last time.

          If you just want to use the behavior, download the sample solution, rip the Wp8nl.Contrib project from it and use it. It just needs a reference to System.Windows.Interactivity.dll, that’s about all.

          Some technical details

          As the inner workings of the behavior are almost identical to that of their Windows 8 counterparts, I am not going to recap everything again. The trick is the same: view models and layer names are stored in and retrieved from attached dependency properties that are attached to the shapes themselves - the behavior uses this how to hold view models and map shapes together, and which shape belongs to which layer. For the technically interested I will stress a few small points. First of all, I already said the map elements themselves don’t have any events. Therefore, I have to attach events to the map, using the “AddEventMappings” method that’s loaded when the behavior’s OnLoad is called:
          private void AddEventMappings()
          {
            foreach (var mapper in EventToCommandMappers)
            {
              var evt = AssociatedObject.GetType().GetRuntimeEvent(mapper.EventName);
              if (evt != null)
              {
                AddEventMapping(mapper);
              }
            }
          }
          
          private void AddEventMapping(EventToCommandMapper mapper)
          {
            Observable.FromEvent<GestureEventArgs>(AssociatedObject, mapper.EventName)
              .Subscribe(se =>
               {
                 var gestureArgs = se.EventArgs;
                 if (gestureArgs != null)
                 {
                   var shape = 
                      AssociatedObject.GetMapElementsAt(
                         gestureArgs.GetPosition(AssociatedObject)).FirstOrDefault(
                           p => MapElementProperties.GetLayerName(p)==LayerName);
                   if (shape != null)
                   {
                     FireViewmodelCommand(
                       MapElementProperties.GetViewModel(shape), mapper.CommandName);
                   }
                 }
               });
          }

          So this works fundamentally different from it’s Windows 8 counterpart: not the shapes respond to events, but the map does so, and reports the shapes found at a location of the tap or the doubletap. The shapes in question can be retrieved using the map’s GetMapElementsAt method. And then I select the first shape I find that has the same layer name in it’s LayerName attached dependency property as the behavior. Note this filter is necessary: the map reports the shapes and it reports all of them - since there is no real layer structure the map has no notion of which behavior put the shape on the map. And you don’t want every behavior reporting all other shapes that happen to be on the same location as well – that would result in double events. But if the behavior finds a hit, it calls the FireViewModelCommand, which is essentially the same as in Windows 8, and it shows the window with alphanumeric info. That part has not been changed at all.

          The rest of the behavior is mainly concerned with adding, removing and replacing shapes again. I would suggest you’d study that if you are interested in how to respond to the various events of an ObservableCollection. To prove that data binding actually works, you can open the menu and select “change dhl building”.  That’s the most eastward building on the map. If you choose that, you will actually see the building change shape. The only thing the TestChangedShapeCommand command - that’s called when you hit that menu item – does, it change a building’s geometry property. The image on the map is updated automatically.

          Some concluding observations

          Somewhere down in the guts of Windows Phone 8 there’s a native control, and I very much think both it and it’s Bing Maps control for Windows 8 counterpart are of the same breed. Both have similar, yet subtly different projections to managed code. As I already mentioned – in Windows 8 the shapes descend from MapShape, in Windows Phone 8 from MapElement. In addition, Windows Phone Map Elements support StrokeColor, StrokeThickness and StrokeDash – no such thing on Windows 8 - one more cheer for the Windows Phone team ;). But neither are supporting complex shapes and things like donuts (polygons with holes in it). These are the hallmarks of the real heavy duty GIS systems like the stuff Cadcorp. ESRI et al are making.

          Also important when sharing code is to note the following:

          • In Windows Phone 7, we made shapes from a LocationCollection, which is a collection of GeoCoordinate
          • In Windows Phone 8, shapes are created from a GeoCoordinateCollection, which is a collection of GeoCoordinate
          • In Windows 8, shapes are created from a LocationCollection which is a collection of Location.

          So both platforms refactored the Locations and their collection, and both in opposite ways. This can be solved by using converters or a generic subclass specific for both platforms but I leave things like that as exercise for the reader. The fun thing is: once again it shows that a lot of code can be reused as long as you keep application and business logic in models and view models – that way, you only have to deal with user interface and platform considerations, but your basic app structure stays intact. Once more: three cheers for MVVM.

          And as usual you can download the sample solution. I will shortly add this stuff to the Windows Phone 8 specific version of the wp7nl library on CodePlex

          Happy mapping on Windows Phone 8!

          Introducing the new Windows Phone 8 Map control

          The time is finally there: the Windows Phone SDK 8.0 is out, and now we can finally talk about all the great news things for developers that this new SDK brings, and I’ll start that right now. And I don’t think it will surprise anyone who knows me that the first thing I did was looking at the much-rumored new maps control.

          map1I was not disappointed. In general, just two words: super slick. The very embodiment of fast and fluid. What Windows Phone 8 brings to the mapping table made by geo hart skip and is nothing short of dramatic. Think the Nokia drive map on your Windows Phone 7. On steroids. As a control. For you to use in your apps. With downloadable maps for use offline. I have seen it run on actual hardware and for me as a GIS buff, used to the fact that maps stuff usually take a lot of processing power and doesn’t necessary always go super fast, this was a serious nerdgasm. So I created a little app to show off the very basics of this map control. It allows you to select the various map modes, as well to to select map heading and pitch. Heading is the direction the top of the map is pointing – in Bing Maps this was always “North”, and Pitch is how you are looking on the map. If that’s 0, you are looking straight from above.

          Now the important the thing about Windows Phone 8 is that the team really went out of their way to make sure code is backwards compatible. That means that not only the new maps control is in the framework, but also Ye Olde Bing Maps control. This can lead to some confusing situations. The important thing to remember when working with the new map control is

          • The (old) Bing Maps control stuff is in namespace Microsoft.Phone.Controls.Maps
          • The new map control stuff in in namespace Microsoft.Phone.Maps.Controls.

          So “Controls” and “Maps” are swapped. I always keep in mind “maps first” as a mnemonic to remember which namespace to use. Especially when you are using ReSharper or a tool like it that most helpfully offers you to add namespaces and references (again) can really get you caught on the wrong foot, so pay attention.

          I started out creating a “New Windows Phone App”, selected OS 8.0 (of course), fired up the Library Package Manager and downloaded my wp7nl library. This gives MVVMLight and some other stuff I need for my sample. At the moment of this writing this is still Windows Phone 7 code but this will run fine (of course this all will be updated shortly). The only thing you need to take care of is that you delete the references to Windows Phone Controls.dll and Windows Phone Controls.Maps.dll the package makes.

          First step is to make a simple view model describing the cartographic modes the new map control supports:

          using GalaSoft.MvvmLight;
          using Microsoft.Phone.Maps.Controls;
          
          namespace MvvmMapDemo1.ViewModels
          {
            public class MapMode : ViewModelBase
            {
              private string name;
              public string Name
              {
                get { return name; }
                set
                {
                  if (name != value)
                  {
                    name = value;
                    RaisePropertyChanged(() => Name);
                  }
                }
              }
          
              private MapCartographicMode cartographicMode;
              public MapCartographicMode CartographicMode
              {
                get { return cartographicMode; }
                set
                {
                  if (cartographicMode != value)
                  {
                    cartographicMode = value;
                    RaisePropertyChanged(() => CartographicMode);
                  }
                }
              }
            }
          }
          

          The main view is basically some properties and a little bit of logic. First part handles the setup and the properties for displaying and selecting the cartographic map modes:

          using System;
          using System.Collections.ObjectModel;
          using System.Device.Location;
          using GalaSoft.MvvmLight;
          using Microsoft.Phone.Maps.Controls;
          
          namespace MvvmMapDemo1.ViewModels
          {
            public class MapViewModel : ViewModelBase
            {
              public MapViewModel()
              {
                modes = new ObservableCollection<MapMode>
                {
                  new MapMode 
                    {CartographicMode = MapCartographicMode.Road, Name = "Road"},
                  new MapMode 
                    {CartographicMode = MapCartographicMode.Aerial, Name = "Aerial"},
                  new MapMode 
                   {CartographicMode = MapCartographicMode.Hybrid, Name = "Hybrid"},
                  new MapMode
                   {CartographicMode = MapCartographicMode.Terrain, Name = "Terrain"}
                };
                selectedMode = modes[0];
              }
              
              private MapMode selectedMode;
              public MapMode SelectedMode
              {
                get { return selectedMode; }
                set
                {
                  if (selectedMode != value)
                  {
                    selectedMode = value;
                    RaisePropertyChanged(() => SelectedMode);
                  }
                }
              }
          
              private ObservableCollection<MapMode> modes;
              public ObservableCollection<MapMode> Modes
              {
                get { return modes; }
                set
                {
                  if (modes != value)
                  {
                    modes = value;
                    RaisePropertyChanged(() => Modes);
                  }
                }
              }
            }
          }
          

          The only important part about this is that there must be an initially selected mode, as the control does not take it very well if the mode is forcibly set to null by the data binding.

          At little bit more interesting are the next two properties of the view model, which control heading and pitch:

          private double pitch;
          public double Pitch
          {
            get { return pitch; }
            set
            {
              if (Math.Abs(pitch - value) > 0.05)
              {
                pitch = value;
                RaisePropertyChanged(() => Pitch);
              }
            }
          }
          
          private double heading;
          public double Heading
          {
            get { return heading; }
            set
            {
              if (value > 180) value -= 360;
              if (value < -180) value += 360;
              if (Math.Abs(heading - value) > 0.05)
              {
                heading = value;
                RaisePropertyChanged(() => Heading);
              }
            }
          }

          The map seems to try to keep its heading between 0 and 360 degrees, but I like to have the slider in the middle for North position – that way you can use it to rotate the map left and right. So I want heading to be between –180 and +180, which should be functionally equivalent to between 0 and 360 - and apparently I get away with it. Since both values are doubles I don’t do the standard equals but use a threshold value to fire a PropertyChanged. Courtesy of ReSharper suggesting this.

          Then there’s a MapCenter property, that doesn’t do very much in this solution apart from setting the initial map center. I have discovered that the center map does not like being set to null either – this beasty is a bit more picky than the Bing Maps control it seems so I take care to set an initial value:

          private GeoCoordinate mapCenter = new GeoCoordinate(40.712923, -74.013292);
          /// 
          /// Stores the map center
          /// 
          public GeoCoordinate MapCenter
          {
            get { return mapCenter; }
            set
            {
              if (mapCenter != value)
              {
                mapCenter = value;
                RaisePropertyChanged(() => MapCenter);
              }
            }
          }
          private double zoomLevel = 15;
          
          public double ZoomLevel
          {
            get { return zoomLevel; }
            set
            {
              if (zoomLevel != value)
              {
                zoomLevel = value;
                RaisePropertyChanged(() => ZoomLevel);
              }
            }
          }

          Together with the initial ZoomLevel set to 15, this will give you a nice view of Manhattan Island, New York City, USA. There's also a boolean property "Landmarks" that will enable or disable landmarks - you can look that up in the sources if you like.

          Then I opened up Blend, plonked in a map, two sliders, a checkbox on the screen, did some fiddling with grids and stuff, and deleted a lot of auto-generated comments. That made me end up with quite a bit of XAML. I won’t show it all verbatim, but the most important thing is the map itself:

          <maps:Map x:Name="map" 
                    CartographicMode="{Binding SelectedMode.CartographicMode,Mode=TwoWay}"
                    LandmarksEnabled="{Binding Landmarks,Mode=TwoWay}"
                    Pitch="{Binding Pitch, Mode=TwoWay}"
                    Heading="{Binding Heading, Mode=TwoWay}" 
                    Center="{Binding MapCenter, Mode=TwoWay}"
                    ZoomLevel="{Binding ZoomLevel, Mode=TwoWay}"
                    Grid.ColumnSpan="2"/>

          Does not look like exactly rocket science, right? It is not, as long as you make sure the maps namespace is declared as:

          xmlns:maps="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps" 

          The horizontal slider, controlling the heading, is defined as follows:

          <Slider Minimum ="-180" Maximum="180" Value="{Binding Heading, Mode=TwoWay}"/>
          The vertical slider, controlling the pitch, looks like this:
          <Slider Minimum="0" Maximum="75" Value="{Binding Pitch, Mode=TwoWay}" />

          Sue me, I took the easy way out and declared the valid ranges in XAML in stead of in my (view) model. But the point of the latter is this: apparently you can only supply ranges between 0 and 75 for pitch. And the pitch is only effective from about level 7 and higher. If you zoom out further, the map just become orthogonal (i.e. viewed straight from above, as if the pitch is 0). This is actually animated if you zoom out using pinch zoom, a very nice visual effect.

          Finally, the list picker controlling which kind of map you see, and the checkbox indicating if the map should show landmarks or not

          <toolkit:ListPicker ItemsSource="{Binding Modes}" 
                              SelectedItem="{Binding SelectedMode, Mode=TwoWay}" 
                              DisplayMemberPath="Name"/>
          <CheckBox Content="Landmarks" IsChecked="{Binding Landmarks, Mode=TwoWay}"/>

          … only I haven’t been able to find any landmarks, not in my hometown Amersfoort, not Berlin nor New York so I suppose this is something that’s not implemented yet ;-)

          CapMapIf you fire up this application you will get an immediate error message indicating that you have asked for the map but that you have not selected the right capability for this in the manifest. So double click on “Properties/WMAppManifest.xml” and select ID_CAP_MAP (yeah, the manifest’s got a nice editor too now), and fire up your app.

          And that’s all there is to your first spin with the new Windows Phone map control. It supports data binding – to an extent, and it’s easy to control and embed. Play with the sliders and scroll over the map – it’s amazingly fast and I can assure you it is even more so on actual hardware. Stay tuned: more is coming on this subject!

          Note: I have not touched upon creating and adding map keys to the map in this solution. This procedure is described here.

          As usual: download the sample solution here.

          03 October 2012

          A WinRT behavior to start a storyboard on an event

          Sometimes I get a bit distracted. In this article I mention a behavior that I wrote which starts a storyboard on an event, I even put in in the win8nl library – and then totally forget to blog about it, or even to announce it. So anyway, when Danny van Neyghem asked me about a problem that was almost solved by my behavior, I kinda remembered it, and that I totally forgot about it - and decided a) to improve it and b) to talk about it (well, write).

          World, meet StartStoryboardBehavior. It’s a very simple behavior that has the following properties:

          Storyboard The name of the Storyboard to start. Mandatory.
          StartImmediately true = don’t wait for an event to start, just start the storyboard when the behavior is loaded. Optional; default is false
          EventName The event of the AttachedObject that will initiate the start of the storyboard (e.g. ‘Click’ on a button). Ignored when StartImmediately  == true, mandatory otherwise
          SearchTopDown Optional, default is true. If true, the behavior will start to search for your storyboard from the top of the visual tree. This is the scenario in which for instance clicking a button will initiate a storyboard that sits somewhere in the top of the page. If this value is set to false, the behavior will search from the attached object up. Choose this setting when you use the behavior to start a storyboard that’s sitting inside a template.

          “SearchTopDown” was added just yet, and I hope it solves Danny’s problem. For those who just want to use the behavior: Nuget Win8nl and you have the behavior armed and ready. I’ve updated the package with the improved behavior already. For those who want to learn – well, it’s not rocket science but read on.

          The first part is not so very interesting – just your basic setting up of the behavior, the wiring up and a wiring down of the events. The only interesting things happen in AssociatedObjectLoaded:

          using System;
          using System.Linq;
          using Windows.UI.Xaml;
          using WinRtBehaviors;
          using System.Reflection;
          using Win8nl.External;
          using Windows.UI.Xaml.Media.Animation;
          using System.Reactive.Linq;
          
          namespace Win8nl.Behaviors
          {
            public class StartStoryboardBehavior : Behavior<FrameworkElement>
            {
              protected override void OnAttached()
              {
                base.OnAttached();
                AssociatedObject.Loaded += AssociatedObjectLoaded;
              }
              
              protected override void OnDetaching()
              {
                AssociatedObject.Loaded -= AssociatedObjectLoaded;
                base.OnDetaching();
              }
          
              private void AssociatedObjectLoaded(object sender, RoutedEventArgs e)
              {
                if (StartImmediately)
                {
                  StartStoryboard();
                }
          
                if (!string.IsNullOrWhiteSpace(EventName))
                {
                  var evt = AssociatedObject.GetType().GetRuntimeEvent(EventName);
                  if (evt != null)
                  {
                    Observable.FromEventPattern<RoutedEventArgs>(AssociatedObject, EventName)
                      .Subscribe(se => StartStoryboard());
                  }
                }
              }
            }
          }

          If StartImmediately is true, the storyboard is fired immediately. If not, the behavior tries to find an event with the name supplied in the EventName property and tries to attach a dynamic handler to it using Rx. Nothing new here, I already described this technique earlier - in the article where I announced this forgotten behavior :-)

          More interesting is this funny little method, that’s basically one big Linq statement:

          private Storyboard GetStoryBoardInVisualDescendents(FrameworkElement f)
          {
            return f.GetVisualDescendents()
              .Where(p => p.Resources.ContainsKey(Storyboard) && p.Resources[Storyboard] is Storyboard)
              .Select(p => p.Resources[Storyboard] as Storyboard).FirstOrDefault();
          }

          It checks in all visual children’s resources for a storyboard with the name supplied in “Storyboard”, and if so, it selects it. It uses the extension method GetVisualDescendents to generate a list of all the children – all the way to the bottom of the visual tree from the element in “f”.

          As for the behavior’s default behavior (meh), it searches top-down for the storyboard, using this method:

          private void StartStoryboardTopDown()
          {
            var root = AssociatedObject.GetVisualAncestors().Last() ?? AssociatedObject;
          
            var storyboard = GetStoryBoardInVisualDescendents(root);
            if (storyboard != null)
            {
              storyboard.Begin();
            }
          }

          In a nutshell: find the very last top object in the visual tree – that is the root. If that’s null, apparently the current associated object already is the root. Then it starts to search downward for the storyboard and if it finds it, it will fire it.

          For the bottom-up strategy, another method is employed, with a very original name:

          private void StartStoryboardBottomUp()
          {
            var root = AssociatedObject;
            Storyboard storyboard;
            do
            {
              storyboard = GetStoryBoardInVisualDescendents(root);
              if (storyboard == null)
              {
                root = root.GetVisualParent();
              }
            } while (root != null && storyboard == null);
          
            if (storyboard != null)
            {
              storyboard.Begin();
            }
          }

          This method starts by trying to find the storyboard in the visual tree below the current associated object. If it doesn’t find it, in moves one level up and tries again. And another one. Till it a) finds the storyboard or b) runs out of levels. If a storyboard is found, then it fires it. Okay, so that’s a little inefficient, but it only happens upon firing the event.

          The final pieces of the puzzle is StartStoryboard, which simply selects the method based upon the SearchTopDown value.

          private void StartStoryboard()
          {
            if( SearchTopDown)
            {
              StartStoryboardTopDown();
            }
            else
            {
              StartStoryboardBottomUp();
            }
          }

          And that’s all there is to it. I’ve omitted the declaration of the four (attached dependency) properties as that only bulks up this post with no actual value, and the complete listing can be found here on CodePlex if that helps you to get overview.

          Screenshot8For those who love to see the behavior in action I created a little sample app, which shows a few items in a ListBox. At the end of each row there’s a button, and if you click that the color of three texts to the left is animated from black to red in about a second. That’s a storyboard being fired by the behavior. Very exiting ;-) - but it proves the point.

          Enjoy! I hope this helps you with your Windows 8 development! Global Availability is coming, get cracking to get your stuff in the store!

          30 September 2012

          Repairing the Windows Phone 7 behavior to show an image background for a search string

          On the last day of 2011 ago I made DynamicBackgroundBehavior - a quite bizarre behavior which plays a supporting role in my latest Windows Phone application “What’s cooking”. It basically shows a picture from a search string as a background, using Bing Image search. Quite neat. Until Microsoft decided to change the Bing Search API a bit. Up until then, it had been a free unlimited ride – since about August you have to buy a package of searches (anything below 5000 searches per month is free). And some more stuff has been changed.

          Microsoft provides a nice little C# client library that should solve all of this using an OData protocol. The sad thing is that for the life of it I could not get it to compile on Windows Phone. So I ended up analyzing the PHP (*shudder*) sample in this document – a Word document no less – to see what I needed to do (see page 27 and further).

          From a coding perspective, the following details have been changed:

          Okay. My cheese moved a little. First things first. I need base64 encoded text. Samples of this are on the internet a dime a dozen, I took this one:

          /// <summary>
          /// Converts string to base64
          /// </summary>
          /// <param name="data"></param>
          /// <returns></returns>
          private string Base64Encode(string data)
          {
            try
            {
              var encData_byte = new byte[data.Length];
              encData_byte = System.Text.Encoding.UTF8.GetBytes(data);
              return Convert.ToBase64String(encData_byte);
            }
            catch (Exception e)
            {
              throw new Exception("Error in Base64Encode" + e.Message);
            }
          }

          Now the method that does the actual calling of the Bing Search API has changed a little, but not very much:

          /// <summary>
          /// Start the image request using Bing Serach
          /// </summary>
          /// <param name="searchString"></param>
          protected void StartGetFirstImage(string searchString)
          {
            if (!string.IsNullOrWhiteSpace(searchString))
            {
              var queryUri =
                string.Format(
                  "https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/Image?Query=%27{0}%27&$top=1&$format=Atom",
                   HttpUtility.UrlEncode(searchString));
              var request = WebRequest.Create(queryUri) as HttpWebRequest;
              request.Headers["Authorization"] = "Basic " + Base64Encode(string.Format("{0}:{0}", BingSearchKey));
              
              var response =
                Observable.FromAsyncPattern<WebResponse>(
                  request.BeginGetResponse, request.EndGetResponse)();
              response.Subscribe(WebClientOpenReadCompleted, WebClientOpenReadError);
            }
          }

          Note the new url. It goes to a different location, the search term must be enclosed by %27 (i.e. the double quote “) and I have to specify a format (Atom). Really interesting is the thing I marked red, for a variety of reasons:

          • Windows Phone’s Response.Headers collection does not sport the Add method. That stopped me a little, until I realized you could poke directly a new key in the collection by using [“Autorization”] =.
          • Now the authentication is Basic, followed by a space, your account key, colon, your key again and that key:key sequence needs to base 64 encoded. Why this is implemented this way – no idea, but it gets your key across – and validated.

          The final thing is that in the callback WebClientOpenReadCompleted I need to use “http://schemas.microsoft.com/ado/2007/08/dataservices” for a namespace,as I already stated.

          And then my little Windows Phone behavior works again. The fixed version can be downloaded here. I will fix my #wp7nl library on codeplex ASAP.

          26 September 2012

          Data binding shapes to the WinRT Bing Maps control – coming from Windows Phone

          Disclaimer: this is not a 101 article. It requires understanding of the basic idea about MVVM, data binding, the MVVMLight messenger, and the use of behavior in Windows 8 XAML.

          Updated for RTM Bing Maps Control October 3 2012

          MVVMLightwp7

          Introduction
          Let me get this straight: I don’t want you to wean off Windows Phone development – far from it. It’s value proposition is great, and it will become much greater still. This article is yet another way to show you how to carry over code and architecture principles between Microsoft’s great tile based operating systems. It’s all about re-using skills and code. C# and XAML code that is.

          Those who have attended my talks about this subject during this year, have seen the application to the right popping up. Basically it generates shapes (be it points, lines or polygons) by data binding from ‘business objects’ - using MVVMLight view models. If you tap any of those shapes, a “SelectCommand” on the bound view model will be fired, and the view model will put itself on the MVVMLight Messenger. Some other view model will listen for those messages, and pop up the info window. The app shows gas stations (points), roadblocks (lines) and buildings (shapes). Don’t go look for the gas stations, they are not there and the fuel prices a way bit behind the (expensive) times, the roadblock are all but one fictional as well. Only the buildings are real – location wise that is. Sources of the original Windows Phone (7) application can be found here:

          Windows Phone map binding recap
          A quick recap: if you want to data bind to a Bing Maps control in Windows Phone, you will go about like this – first, you would define a data template for a layer:

          <DataTemplate x:Key="RoadBlockViewModelTemplate">
            <Microsoft_Phone_Controls_Maps:MapPolyline Locations="{Binding Geometry}"
                                   Stroke="#FF71FF00"
                                   StrokeThickness="5">
              <i:Interaction.Triggers>
                <i:EventTrigger EventName="Tap">
                  <GalaSoft_MvvmLight_Command:EventToCommand 
                       Command="{Binding SelectCommand}" />
                </i:EventTrigger>
              </i:Interaction.Triggers>
            </Microsoft_Phone_Controls_Maps:MapPolyline>
          </DataTemplate>
          This would be able to make a line geometry from a viewmodel containing a “Geometry” attribute containing a LocationCollection object, and an ICommand “SelectCommand” that is executed when the user taps the line. Second, you would make a Bing Maps control, and define a layer like this.
          <Microsoft_Phone_Controls_Maps:Map x:Name="map"
              CredentialsProvider="Your-credentials-here">
            <Microsoft_Phone_Controls_Maps:MapLayer 
               x:Name="MapLayer_RoadBlocks">
              <Microsoft_Phone_Controls_Maps:MapItemsControl 
                ItemsSource="{Binding RoadBlocks}" 
                ItemTemplate="{StaticResource RoadBlockViewModelTemplate}"/>
            </Microsoft_Phone_Controls_Maps:MapLayer>
          </Microsoft_Phone_Controls_Maps:Map>;

          The roadblock view model would look like this:

          using System.Windows.Input;
          using GalaSoft.MvvmLight;
          using GalaSoft.MvvmLight.Command;
          using GalaSoft.MvvmLight.Messaging;
          using Microsoft.Phone.Controls.Maps;
          using MvvmMaps.Logic.Models.GeoObjects;
          using MvvmMaps.Logic.Models.Geometries;
          using Wp7nl.Utilities;
          
          namespace MvvmMaps.Logic.ViewModels
          {
            public class RoadBlockViewModel : ViewModelBase
            {
              public RoadBlock Model { get; set; }
          
              // Some code omitted
          [DoNotSerialize] public LocationCollection Geometry { get { var modelGeom = Model.Location as LineGeometry; return modelGeom.GetLocationCollection(); } set { var modelGeom = Model.Location as LineGeometry; modelGeom.SetLocationCollection(value); } } [DoNotSerialize] public ICommand SelectCommand { get { return new RelayCommand( () => Messenger.Default.Send(this), () => true); } } } }

          Basically it comes down to a Geometry view model property that converts a business object geometry to and from something the Bing Maps control understands – a LocationCollection. This is a named collection that contains objects of type GeoCoordinate – your basic Lat/Lon container. As said above, when you tap select the MVVMLight Messenger just sets off the selected viewmodel, and ‘something’  should capture that message and handle it.

          Going to Windows 8 – challenges
          Now let’s re-use our skills on Windows 8. Simply put – in its current state, the data binding support for the Bing Maps SDK for Windows Store apps is pretty easy to describe with one word – non-existent. Some developers immediately go into the ‘blame-and-flame-the-Microsoft-dev-team’ mode when they encounter things like this. I think ‘CodePlex library’. I always see things like this as an intellectual challenge, a chance to contribute to the community, and fortunately there are more people thinking that way. My very smart fellow Dutch developer community member Dave Smits has created BindableRTMaps, which is very useful for binding point objects – but its shape support is a bit limited. Being a GIS professional and an MVVMLight junkie, I want the control to be able to generate geographical elements directly from view models, just like I was able to do in Windows Phone. I solved the data binding issue for shapes using a Behavior based upon my WinRtBehaviors library. Not quite surprising for those who know me.

          The result can be seen below:

          Screenshot (9)

          In the center, next to the river, the Vicrea offices, where I work. Say cheese fellows! ;-) As you can see, the shapes are beautifully re-projected when Birds’ Eye View is selected. This is the stuff that makes a GIS buff tick.

          Researching the control I quickly found the following:

          • There’s no data binding support at all (as stated)
          • The shapes the control draws cannot be templated. They are apparently just projections of something native (as is the map itself).
          • There are only two kinds of shapes: MapPolygon and MapPolyline, both descending from MapShape, which in turn descends from DependencyObject – which is very fortunate, as I hope will become clear over the course of this article.

          So I had the challenge to create something that can be put into XAML to still give the designer an amount of control how things appear, without having to resort to code.

          Introducing MapShapeDrawBehavior 
          The behavior I created is called MapShapeDrawBehavior  (I’ve never been one for original catchy names) and can be used like this:

          <Maps:Map Credentials="Your-credentials-here">
            <WinRtBehaviors:Interaction.Behaviors>
            
              <MapBinding:MapShapeDrawBehavior 
                 LayerName="Roadblocks" 
                 ItemsSource="{Binding RoadBlocks, Mode=TwoWay}" 
                 TapCommand="SelectCommand" PathPropertyName="Geometry" >
                   <MapBinding:MapShapeDrawBehavior.ShapeDrawer>
                     <MapBinding:MapPolylineDrawer Color="Green" Width="10"/>
                   </MapBinding:MapShapeDrawBehavior.ShapeDrawer>
              </MapBinding:MapShapeDrawBehavior>
            
            </WinRtBehaviors:Interaction.Behaviors>
          </Maps:Map>

          For every category of objects there’s a layer – which translates to one behavior per list of objects, in this case the road blocks (the green line on the app sceenshot above). Then you need to define three things per layer:

          • What command in the item view model (in this case, a RoadBlockViewModel) must be fired when a MapShape’s only event – Tap – is called.
          • Which property in the item view model contains the Path – this is the terminology for a MapShape’s collection of points. This is, once again, of type LocationCollection. Only that’s no longer a collection of GeoCoordinate but of Location.
          • Finally, you need to define a drawer. A drawer is a concept I sucked from my own thumb – it determines how a collection of points is supposed to be transformed to something on the map. It’s my way to make something that’s not templatable more or less configurable.

          I created three drawers out of the box: MapPolylineDrawer, MapPolygonDrawer, and MapStarDrawer. The last one draws a configurable star shaped polygon around a point – since map shapes cannot be points by themselves. A drawer needs only to implement one method:

          public override MapShape CreateShape(object viewModel, LocationCollection path)

          The basic drawers don’t do anything with the view model: they just take the settings from XAML. But if you want for instance your shapes having different colors based upon some view model property – say you want to color urban areas based upon their crime rate (what we GIS buffs call a thematic map) – you can write a little custom drawer.

          If you just want to use the behavior you are done with reading. You can download the demo solution with code (which, incidentally, shows off a lot of more things than just binding to a map) and start playing around with it. Be aware of the following issues/caveats:

          • You will need to install the Bing Maps SDK for Windows Store apps first
          • When I moved the solution from my Big Black Box to my slate I had to delete and redo all references to Bing.Maps and “Bing Maps for C#, C++, or Visual Basic” (this was using the Beta, I don’t know if that still applies to the RTM version)
          • The control apparently contains native code, so you cannot build it for Any CPU.
          • The designer only works when you build for x86 (this still the case in RTM)

          For the technically interested I will continue with some gory details.

          The inner guts
          The behavior itself is actually pretty big, so I won’t repeat all code verbatim; I will concentrate on the interesting parts.

          First of all, I already mentioned the fact MapShape descends from DependencyObject. That spells ‘Ahoy, Attached Dependency Property ahead!’  to me. So I created two of those, one holding the name of the layer (I use those to find out which shapes belong to a single layer) and one in which I store the view model from which the shape was created:

          using Windows.UI.Xaml;
          
          namespace Win8nl.MapBinding
          {
            public static class MapElementProperties
            {
              public static readonly DependencyProperty ViewModelProperty =
                   DependencyProperty.RegisterAttached("ViewModel",
                   typeof(object),
                   typeof(MapElementProperties),
                   new PropertyMetadata(default(object)));
          
              // Called when Property is retrieved
              public static object GetViewModel(DependencyObject obj)
              {
                return obj.GetValue(ViewModelProperty) as object;
              }
          
              // Called when Property is set
              public static void SetViewModel(
                 DependencyObject obj,
                 object value)
              {
                obj.SetValue(ViewModelProperty, value);
              }
          
              public static readonly DependencyProperty LayerNameProperty =
                   DependencyProperty.RegisterAttached("LayerName",
                   typeof(string),
                   typeof(MapElementProperties),
                   new PropertyMetadata(default(string)));
          
              // Called when Property is retrieved
              public static string GetLayerName(DependencyObject obj)
              {
                return obj.GetValue(LayerNameProperty) as string;
              }
          
              // Called when Property is set
              public static void SetLayerName(
                 DependencyObject obj,
                 string value)
              {
                obj.SetValue(LayerNameProperty, value);
              }
            }
          }

          The core of the MapShapeDrawBehavior self consists out of just five little methods, and the VERY core method is CreateShape. The behavior iterates over the object list databound to ItemsSource, and calls CreateShape for every view model:

          /// <summary>
          /// Creates a new shape
          /// </summary>
          /// <param name="viewModel"></param>
          /// <returns></returns>
          private MapShape CreateShape(object viewModel)
          {
            var path = GetPathValue(viewModel);
            if (path != null && path.Any())
            {
              var newShape = CreateDrawable(viewModel, path);
              newShape.Tapped += ShapeTapped;
          
              MapElementProperties.SetViewModel(newShape, viewModel);
              MapElementProperties.SetLayerName(newShape, LayerName);
          
              // Listen to property changed event of geometry property to check 
              // if the shape needs tobe redrawed
              var evt = viewModel.GetType().GetRuntimeEvent("PropertyChanged");
              if (evt != null)
              {
                Observable
                  .FromEventPattern<PropertyChangedEventArgs>(viewModel, "PropertyChanged")
                  .Subscribe(se =>
                               {
                                 if (se.EventArgs.PropertyName == PathPropertyName)
                                 {
                                   ReplaceShape(se.Sender);
                                 }
                               });
              }
              return newShape;
            }
            return null;
          }
          • First, it reads the view model property that holds the geometry (or at least, it tries that)
          • It creates the actual shape
          • It attaches an event listener to the “Tapped” event
          • It puts the view model and the layer name in attached dependency properties for said shape
          • Finally it attaches a property changed listener so that when the property that’s holding the view model’s geometry changes, the ReplaceShape method is called (which replaces the shape on the map – duh)

          GetPathValue is a simple method that retrieves the view model’s geometry using reflection. Nothing special there:

          private LocationCollection GetPathValue(object viewModel)
          {
            if (viewModel != null)
            {
              var dcType = viewModel.GetType();
          
              var methodInfo = dcType.GetRuntimeMethod("get_" + PathPropertyName, 
                               new Type[0]);
              if (methodInfo != null)
              {
                return methodInfo.Invoke(viewModel, null) as LocationCollection;
              }
            }
            return null;
          }

          CreateDrawable – well that’s VERY simple. Get the drawer and let it decide how the shape will look

          protected virtual MapShape CreateDrawable(object viewModel, LocationCollection path )
          {
            var newShape = ShapeDrawer.CreateShape(viewModel, path);
            return newShape;
          }

          And finally ShapeTapped and FireViewModelCommand:

          private void ShapeTapped(object sender, TappedRoutedEventArgs e)
          {
            var shape = sender as MapShape;
            if( shape != null )
            {
              var viewModel = MapElementProperties.GetViewModel(shape);
              if( viewModel != null )
              {
                FireViewmodelCommand(viewModel, TapCommand);
              }
            }
          }
          
          private void FireViewmodelCommand(object viewModel, string commandName)
          {
            if (viewModel != null && !string.IsNullOrWhiteSpace(commandName))
            {
              var dcType = viewModel.GetType();
              var commandGetter = dcType.GetRuntimeMethod("get_" + commandName, new Type[0]);
              if (commandGetter != null)
              {
                var command = commandGetter.Invoke(viewModel, null) as ICommand;
                if (command != null)
                {
                  command.Execute(viewModel);
                }
              }
            }
          }

          ShapeTapped checks if it the object sending the event is actually a shape, then tries to retrieve a view model from the attached dependency property, and calls FireViewModelCommand on it. Which basically is directly ripped from my earlier EventToCommandBehavior. And then the circle is round again – user taps, view model command is called (just as Laurent Bugnion’s EventToCommand trigger did for Windows Phone) and the view model takes it further just like before.

          There’s more to this behavior, but mostly it’s just reacting to events that occur when the ObservableCollection ItemsSource changes.

          Some concluding remarks
          Of course this behavior was geared to make the code I already had as much reusable as possible, but I think the way WinRT XAML apps and Windows Phone apps can be put together are remarkably similar – provided you make good use of MVVM and keep your code as clean as possible. So what did I have to do to move over my business and view model code to get this working? Well not very much, actually.

          • A tiny thing in my model library because I was so clever to use a BackgroundWorker somewhere in my models – which is not supported in WinRt
          • The Gas station view model was changed to do the conversion form business object geometry to Bing Maps’ Location in stead of the converter I originally - because my solution does not support converters.
          • I had to change some name spaces and data types. Mainly GeoCoordinate was now called Location.
          • Oh yeah – in stead of "clr-namespace" I had to use "using" for declaring namespaces in XAML. I used ReSharper toalt-enter trough the errors and add the namespaces almost automatically.

          And that was about it. Of course, the code in it was quite trivial, but still. On the XAML side things were a bit more complicated:

          • Converters and Attached Dependency Properties were carried over with minimal changes.
          • I had to trash my geometry templates and had to write the behavior to emulate the templates – in a way, which admittedly was no small feat. But that’s a hole that only needs to be plugged once, and can now act as a base for possible better solutions.
          • I had to do some fiddling around with the DataTemplateSelector – that works a wee bit different, and will be subject of a future blog post.
          • ‘Tombstoning’ works a bit differently, but quite analogous. Been there, done that, wrote the blogpost.
          • The App Bar on Windows 8 has a lot more possibilities. And – thank Saint Sinofsky and his minions – it supports data binding out of the box. Moving from Windows Phone app bars to Windows 8 app bars is quite easy. Provided you used the BindableApplicationbar and MVVM of course ;-) 
          • I kinda 1:1 copied the data window (the popup with alphanumeric data that appears when you tap a shape) – that worked remarkably well, but you might want to do something about the styling for a real-world application. The data window is a wee bit small now and does fit in styling wise ;-)

          This is still a work in progress, but I think for basic shape data binding this is already very usable. The Bing Maps control is very fast, courtesy of native code, no doubt. I hope this will help people.

          Once again, for those who don’t feel scrolling all the way up: the source code. Also updated for RTM. Enjoy!

          10 August 2012

          A WinRT behavior to turn a FlipView into a kind of Windows 8 Panorama

          IC425813(UPDATED for RTM August 18 2012)
          One of the most beautiful controls of Windows Phone is the Panorama. It’s ideal for showing a lot related content on a small screen and enable the user to easily pan trough it. A visual cue for ‘there is more’ is provided by showing a little part of the next panel to the very right of the current data. A typical example is showed right.

          It’s also one of the most abused controls (guilty as charged Your Honor), but still I wanted to port Catch’em Birds to Windows 8 – and I found out there was no ready-to-use control. After fighting with ScrollViewers and GridViewers and whatnot I came to this very simple behavior, which basically takes a FlipView and hammers it into a kind of Panorama.

          Now the FlipView is designed to be a full-screen control so the behavior basically walks past all the items in the FlipView, shrinks them horizontally by a configurable percentage of the screen, and displaces the ‘next’ panel a little to the left (making it appear at the right side of the screen on the current panel). To make this look a little bit more fast and fluid, I have made the displacement itself animated, so that the ‘next’ screen not so much snaps as glides into view. The overall effect looks pretty nice to me. I hope Microsoft will think so as well, as my app is up for an App Excellence Lab soon ;-)
          In my app it looks like this. I still lack a decent screen recorder for Windows 8, so I took out the video camera

          So this behavior, most originally called “FlipViewPanoramaBehavior” is of course based upon my earlier WinRtBehaviors CodePlex project. It starts out like this, with the following dependency properties:
          using System;
          using System.Collections.Generic;
          using System.Linq;
          using System.Threading.Tasks;
          using Win8nl.External;
          using Win8nl.Utilities;
          using WinRtBehaviors;
          using Windows.Foundation;
          using Windows.UI.Xaml;
          using Windows.UI.Xaml.Controls;
          using Windows.UI.Xaml.Media;
          using Windows.UI.Xaml.Media.Animation;
          
          namespace Win8nl.Behaviors
          {
            /// <summary>
            /// A behavior to turn a FlipView into a kind of panorama
            /// </summary>
            public class FlipViewPanoramaBehavior : Behavior<FlipView>
            {
              #region AnimationTime
          
              /// <summary>
              /// AnimationTime Property name
              /// </summary>
              public const string AnimationTimePropertyName = "AnimationTime";
          
              public int AnimationTime
              {
                get { return (int)GetValue(AnimationTimeProperty); }
                set { SetValue(AnimationTimeProperty, value); }
              }
          
              /// <summary>
              /// AnimationTime Property definition
              /// </summary>
              public static readonly DependencyProperty AnimationTimeProperty = 
                DependencyProperty.Register(
                  AnimationTimePropertyName,
                  typeof(int),
                  typeof(FlipViewPanoramaBehavior),
                  new PropertyMetadata(250));
          
              #endregion
          
              #region NextPanelScreenPercentage
          
              /// <summary>
              /// NextPanelScreenPercentage Property name
              /// </summary>
              public const string NextPanelScreenPercentagePropertyName = 
                "NextPanelScreenPercentage";
          
              public double NextPanelScreenPercentage
              {
                get { return (double)GetValue(NextPanelScreenPercentageProperty); }
                set { SetValue(NextPanelScreenPercentageProperty, value); }
              }
          
              /// <summary>
              /// NextPanelScreenPercentage Property definition
              /// </summary>
              public static readonly DependencyProperty NextPanelScreenPercentageProperty = 
                DependencyProperty.Register(
                  NextPanelScreenPercentagePropertyName,
                  typeof(double),
                  typeof(FlipViewPanoramaBehavior),
                  new PropertyMetadata(10.0));
              #endregion
            }
          }
          So “AnimationTime” is the number of milliseconds the behavior takes to glide the next panel into view, and NextPanelScreenPercentage is an indication of how much screen real estate the next panel will take. Nothing special here yet.

          If I want to muck around with a FlipView contents, I first have to find these contents. With some breakpoints and watches I found out I could use the following code to find the FlipViewItems:
          /// <summary>
          /// Find all Flip view items
          /// </summary>
          /// <returns></returns>
          private List<FlipViewItem> GetFlipViewItems()
          {
            var grid = AssociatedObject.GetVisualChildren().FirstOrDefault();
            if (grid != null)
            {
              return grid.GetVisualDescendents().OfType<FlipViewItem>().ToList();
            }
            return null;
          }
          Attentive readers might observe that neither GetVisualChildren nor GetVisualDescendents are part of the WinRT api, which is perfectly correct – they come from the VisualTreeHelperExtensions I ported from Windows Phone some time ago. Don’t start to download this stuff and build it together yourself – wait till the end and I will show the lazy way to do this.

          Anyway – I wanted to move the FlipView’s contents fluently. That means I will use some Storyboards to work on Translations. So we identify the contents of each FlipViewItem and set its fist visual child’s Rendertransform to CompositeTransform, if that’s not already present:
          /// <summary>
          /// At compositions transforms to every item within every flip view item
          /// </summary>
          private void AddTranslates()
          {
            var items = GetFlipViewItems();
            if (items != null && items.Count > 1)
            {
              foreach (var item in items)
              {
                var firstChild = item.GetVisualChild(0);
                if (!(firstChild.RenderTransform is CompositeTransform))
                {
                  firstChild.RenderTransform = new CompositeTransform();
                  firstChild.RenderTransformOrigin = new Point(0.5, 0.5);
                }
              }
            }
          }
          This assumes every FlipViewItem contains just one child. You better make sure it does for this to work, so put a Grid around it if you need more than one thing to sit in there.

          Now the core of the whole behavior is this one piece of code:
          /// <summary>
          /// Does the actual repositioning and sizing of the items displayed in the Flipview
          /// </summary>
          private void SizePosFlipViewItems()
          {
            AddTranslates(); // <-- moved from AssociatedObjectLoaded for RTM
            var size = AssociatedObject.ActualWidth*(NextPanelScreenPercentage/100);
            var shift = size - 15;
          
            var items = GetFlipViewItems();
            if (items != null && items.Count > 1)
            {
              // Make all items a bit smaller and make sure they are aligned left
              foreach (var item in items)
              {
                item.GetVisualChild(0).HorizontalAlignment = HorizontalAlignment.Left;
                item.GetVisualChild(0).Width = items[0].ActualWidth - size;
              }
          
              var selectedIndex = AssociatedObject.SelectedIndex;
          
              if (selectedIndex > 0)
              {
                StartTranslateStoryBoard(0, 0, 
                                         items[selectedIndex - 1].GetVisualChild(0), 0);
              }
          
              StartTranslateStoryBoard(0, 0, items[selectedIndex].GetVisualChild(0), 
                                       AnimationTime);
          
              if (selectedIndex + 1 < items.Count)
              {
                StartTranslateStoryBoard(-shift, 0,
                                          items[selectedIndex + 1].GetVisualChild(0), 
                                          AnimationTime);
              }
            }
          }
          
          First it calculates the new size of the FlipViewItems, and then it calculates how much it can shift the ‘next panel’ – basically, how much room is there between this panel and the next. This is currently a hard coded number, but feel free to make that a property as well ;-).

          Then, for every FlipViewItem it makes the first visual child “size” smaller, and makes sure it’s aligned to the left (so space comes free and the right side). Then:
          1. It moves the panel that just disappeared to the left (if any) back  to it’s normal position, in no time (i.e. not animated – it’s invisible to the leftanyway, so why bother).
          2. It moves the current panel to its normal position, but it animates it. This is because if it’s moved in from the left, it moves a bit too far, as you might have noticed in the movie – so it glides back
          3. It moves the next panel (if any) a little bit to the left – animated, so it glides into view on the right hand side of the screen.
          Now of course there is the slight matter of the method that make the storyboards to make it happen:
          private static void StartTranslateStoryBoard(double desiredX, double desiredY, 
                                                       FrameworkElement fe, int time)
          {
            var translatePoint = fe.GetTranslatePoint();
            var destinationPoint = new Point(desiredX, desiredY);
            if (destinationPoint.DistanceFrom(translatePoint) > 1)
            {
              var storyboard = new Storyboard { FillBehavior = FillBehavior.HoldEnd };
              storyboard.AddTranslationAnimation(
                   fe, translatePoint, destinationPoint,
                   new Duration(TimeSpan.FromMilliseconds(time)),
                   new CubicEase { EasingMode = EasingMode.EaseOut });
              storyboard.Begin();
            }
          }
          Once again, I use some extension methods from code ported from Windows Phone in the article I mentioned before, I underlined them to make them distinguishable from the standard API. Basically: this method accepts a FrameworkElement and moves it to a desired position in a desired time, using a storyboard that animates a translation. That is to say, unless it is already in that desired position. I think I will make this into a separate extension method in a utilities library one day but for the moment it’s doing fine.

          All that’s left now is some wiring up, I cobbled that all together in one code block:
          protected override void OnAttached()
          {
            AssociatedObject.Loaded += AssociatedObjectLoaded;
            base.OnAttached();
          }
          protected override void OnDetaching()
          {
            AssociatedObject.Loaded -= AssociatedObjectLoaded;
            AssociatedObject.SelectionChanged -= AssociatedObjectSelectionChanged;
            AssociatedObject.SizeChanged -= AssociatedObjectSizeChanged;
          }
          
          private void AssociatedObjectLoaded(object sender, RoutedEventArgs e)
          {
            //AddTranslates(); deleted for RTM
            SizePosFlipViewItems();
            AssociatedObject.SelectionChanged += AssociatedObjectSelectionChanged;
            AssociatedObject.SizeChanged += AssociatedObjectSizeChanged;
          }
          
          private async void AssociatedObjectSelectionChanged(object sender, 
                                                              SelectionChangedEventArgs e)
          {
            await Task.Delay(250); // Updated after bug report from SCPRedMage
            SizePosFlipViewItems();
          }
          
          private async void AssociatedObjectSizeChanged(object sender, 
                                                         SizeChangedEventArgs e)
          {
            await Task.Delay(250);
            SizePosFlipViewItems();
          }
          OnAttached and OnDetaching do their usual basic wiring and unwiring of events.
          When the AssociatedObject (i.e. the FlipView) is first loaded the FlipViewItems’ first child gets their CompositeTransforms, then the initial screen layout is created by calling SizePosFlipViewItems. Then two events are wired up:
          • SelectionChanged
          • SizeChanged
          Now the first one is logical – when the user selects the next panel (i.e. he scrolls it in from the left or right) the panels need to be arrange again so that the newly selected panel stays in view (it scrolls too much to the right, remember) and the ‘new’ next panel comes into view at the left hand side of the screen.

          The SizeChanged intercept is necessary for when the user rotates his screen or snaps the application. For then the size of the screen changes, and the portion of the screen that the next panel may use is considerably smaller – in pixels. In my app this is taken care of by a Visual State Manager that listens to page events – basically something stolen from the LayoutAwarePage that’s in every template project – but that takes a while. Now I know I am going to be lambasted for this (and I have a pretty good idea by whom), but to solve this the SizeChanged handler waits a bit for actually calling SizePosFlipViewItems. And to prevent UI blocking I interestingly abused Task.Delay for that. It’s crude, but it works. As you may have seen in the movie when I snapped the app.

          So there you have it. The code works, you have seen it in action. Its usage is ridicilously simple: make a FlipView, add items, and add this behavior to the FlipView. Done. You can download the the behavior here but you will need quite some base libs to get it working – as it uses a lot of my win8nl library on CodePlex. If you want to go the easy and quick way: just use the Win8nl NuGet package. That will get you the behavior and all the prerequisites, including MVVMLight.

          Be aware that win8nl now uses the Reactive extensions. They are included in the NuGet package and they will come with it as a dependency

          UPDATE: Please note there is a tiny code change since original publication: due to Microsoft optimizing the FlipView not all elements are initially loaded, so the check if every FlipViewItem child has a CompositeTransform has to performed at every manipulation.

          UPDATE 2: There's a tiny update to AssociatedObjectSelectionChanged. And those who want a simple working sample, download the sources from codeplex and fire up FlipViewTest.XAML as the start page.