WP7Contrib – Bing Maps REST Service Wrappers

Are you using or thinking about using Bing Maps REST Services in your application ? Finding issues with performance with the wsdl endpoints ? Would prefer to use a REST approach ?

Well, look no further, there is now a simple way for you to do all of the above…

For those folks out there that are building location based apps for WP7 or those that are thinking about one we are very excited to announce the first release of the Bing Maps Rest API wrapper classes that have recently been added to the WP7Contrib (WP7C). Unfortunately, it has taken some time to develop mainly due to the iceberg like API. When I first had the idea a simple prototype proved that it was possible along with some shout outs to those folks on Twitter to see who was taking advantage of the services it became obvious very quickly that this was a feature people were using or wanted to use. Based on some of the feedback it was apparent that people were building their own wrappers and hand cranking the client side requests, responses and classes to hold data. This is great but I wanted a more generic and reusable set of components that all WP7 developers  can take advantage of, like the majority of developers we want a simple non-intrusive mechanism for incorporating the different features that these services provide into your apps.

When I originally started out using the Bing services I hooked up to the wsdl endpoints but I have always been uncomfortable using this approach especially when we have the WP7C Resource Client at our disposable which provides a simple Rx mechanism for dealing with request response for talking to endpoints. I was also concerned with the bulky and heaviness of this approach, sure it works and works well on a Silverlight browser app or .Net apps. However, as obvious as it may sound we don’t have that sort of processing power on the device. So, a lighter more performant approach was required ensuring that we can take advantage of the location based services on the device and incorporate this with Bing services REST API.

First before we start to dig into the services I want to give a quick overview of each of them :-

  • Route Service – provides clients with the ability to calculate a route from a Geo Coordinate location to another. There are a number of different variants that are catered for here including; a Point of Interest; and also major travel routes.
  • Imagery Service – provides clients with the ability to request different types of imagery. There are a number of different variants that are catered for here including; centre point Geo Coordinate location, for a particular route; and for a particular area by providing North East and South West Geo Coordinates that specific the area the client is interested in.
  • Location Service – provides clients with the ability to search in your immediate/local area for shops, bars, facilities etc
  • Search Service – provides clients with the ability to search a particular area for a variety of different amenities that the client is interested in.

Each of these different scenarios have been built and illustrated in the Bing Maps project that can be found in the Spikes folder of the WP7C, now I am sure that there are more scenarios and if you have any these we would be very interested in hearing from you. What these samples show are the basics that you need in order to incorporate them into your apps. The other very important note is that for ease of building the samples I have used a Pivot control as this was the simplest way for me to test the service wrappers were working as expected but also for me to group them together, I am strongly against putting map controls into both Pivot or Panorama controls as the User Experience is simply wrong. However, there is an exception to the rule here and that if you are using a static map via the Imagery Service as this is essentially an image.

So, exciting news, and we are certain that this new Bing Maps REST API wrapper will help make developers lives less painful when building location based applications, we are therefore very excited to hear about any of the apps you eventually build using these. Also, if you have any suggestions or feedback on the implementation or additional features that you would find useful please contact me so that we can discuss.  Over the next couple of articles I will dig into each of the services in the spikes folder of WP7C and link off to Ollie who has some deep dive articles to help supplement the introductory blogs.

Enjoy!

uk tech.days 2011

This week Ollie and I will presenting at the UK tech.days happening in the Fulham, London.

Our first session will be all about building Data Data Intensive apps for WP7 and we are really looking forward to talking to you about what we have learnt building these types of applications. We are also going to show off bits from the WP7 Contrib that help to make building these types of applications easier. It’s going to be a demo packed session so hold on for a rollercoaster ride. We are making avaliable all our demos before the session so if you are attending and interested you can download these from the skydrive link at the bottom of the post.

My other session obviously will be about using Blend =P  and the title of the session is aptly named “Expression Blend for Silverlight Developers”.

The session is broken down into 3 sub sections; designer developer collaboration; Blend quick fire tips; and the main part, building out an app from a Adobe Photoshop/Illustrator visual design into a functional Silverlight app. This session is aimed particularly at developers who are just starting out with Blend, however even if you have been using Blend for a while there should be plenty of refreshers.

Now, I had thought about doing

“… this is how I create a button in Blend, and oh look I can make it into a circle and bounce across the screen…”

as much as I love attending these sessions and love the buzz afterwards sometimes it can be difficult to relate the content to a problem you may currently be working on.

Up on skydrive you will find; the .psd file I am going to use; an unstyled version; and a completed version that is styled. There is still plenty more to do so the scope is open and hopefully you will be able to use this as a reference point for future apps that you build. Therefore, I thought that it would be an interesting idea to see how attendees if they so wished can use the session as a hands-on Blend training hour, and if you want to participate then you can. Otherwise you can sit back and watch how we build a static vector graphic into a functioning app.

If you are planning on attending and would like me to cover off anything in particular I will do my best to make it happen, otherwise I would be more than happy to chat during the event, if you can bring code or have a scenario that would really help me understand the context of your questions.

You can find all of the goodies up on the sky drive folder.

See you there!

 

WP7Contrib – Page Transitions and Navigation Service

I finally got around to updating the page transistions in wp7 contrib last week, its something that has been on my list for awhile. For a complete sample project check out the sample in the spikes folder where you can also find lots of other samples illustrating other tennants of the contrib.

The transitions used in the WP7C are based around the great work of Kevin Marshall who originally created the transitions, we like them becuase they are lighter on memory usage and slightly faster when compared to the page transitions found in the WP7 toolkit. Now that is not too say I dislike the transitions in the toolkit, I actually really like them mainly because we have the ability to define these transitions in Xaml and hopefully there will be some future design-time support in Blend where we could run these transitions. Xaml support for the transitions is definately on the vNext list for the WP7C as we believe its important for designers to able to change, apply and understand the different transitions that are available.

When comparing implementation details, the toolkit uses a custom Frame called a Transition Frame; and WP7C does this at a page level all the pages in your app have to sub class the Animated Base Page. Other differences include; the toolkit uses a Render Transform and WP7C uses Composite Transform; the WP7C uses the XamlReader.Load to setup the storyboards, however the toolkit has specific loose Xaml files that contain the storyboards.

So the new page transitions includes the different Rotate permutations for your page transitions, I also added in some new slide and fade transitions. You can play with these and all the other different transitions by downloading the sample app.

The other thing that I decided to add into the app was a very simple implementation of the WP7C navigation service. Page transitions and navigation are interconnected, when you navigate to a page you want to execute a transition between the current page and the new page, this is approapiate when going forwards or backwards. Normally we would wire up the WP7C Navigation Service in the bootstrapper of our app and use a DI framework to new this up. In order to keep everything super simple I am using the interface and manually newing up an instance, also note that I am not using a View Model this is simply to show the flexibility of the WP7C Navigation Service.

private WP7Contrib.Services.Navigation.INavigationService navigationService;

public MainPage()
{
        InitializeComponent();

       AnimationContext = LayoutRoot;
       this.navigationService = new WP7Contrib.Services.Navigation.ApplicationFrameNavigationService(
                                   ((App)Application.Current).RootFrame);
}

Notice how we grab the RootFrame and pass this in to the constructor of the WP7C Navigation Service the same code can be used in a bootstrapper. When using the WP7C transitions there is no requirement for us to change the base class of the frame in the App’s Initalize Phone App handler like we would do when using the toolkit.

private void InitializePhoneApplication()
{
    if (this.phoneApplicationInitialized)
    {
        return;
    }

    // Create the frame but don't set it as RootVisual yet; this allows the splash
    // screen to remain active until the application is ready to render.
    this.RootFrame = new TransitionFrame();
    this.RootFrame.Navigated += this.CompleteInitializePhoneApplication;

    // Handle navigation failures
    this.RootFrame.NavigationFailed += RootFrame_NavigationFailed;

    // Ensure we don't initialize again
    this.phoneApplicationInitialized = true;
}

Instead we need to hang all our pages from the Animated Base Page, pay close attention to; the constructor where we assign the Animated Context of our base page to the LayoutRoot of our page; and the overridden Get Animation where we are deciding which transitions to fire based on the Animation Type.

namespace PageTransition
{
    using System;

    using WP7Contrib.View.Transitions.Animation;

    public partial class Slide : AnimatedBasePage
    {
        public Slide()
        {
            InitializeComponent();

            AnimationContext = LayoutRoot;
        }

        protected override AnimatorHelperBase GetAnimation(AnimationType animationType, Uri toOrFrom)
        {
            if (animationType == AnimationType.NavigateForwardOut)
            {
                return new SlideLeftFadeOutAnimator { RootElement = LayoutRoot };
            }

            if (animationType == AnimationType.NavigateBackwardOut)
            {
                return new SlideRightFadeOutAnimator { RootElement = LayoutRoot };
            }

            if (animationType == AnimationType.NavigateForwardIn)
            {
                return new SlideLeftFadeInAnimator { RootElement = LayoutRoot };
            }

            return new SlideRightFadeInAnimator { RootElement = this.LayoutRoot };};
        }
    }
}

For completeness I have covered off the different permutations of Navigating forward or backward. The implemented page transitions have a corresponding Animator which makes it straightforward to implement the type of animation that you require. And that is everything you need in order to get page transitions working in your app. Once you have implemented the transitions you want then its a fairly simple task of using the WP7C Navigation Service to navigate to a page in your app.

private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (AnimationList.SelectedIndex != -1)
    {
        switch (AnimationList.SelectedIndex)
        {
            case 0:
                this.navigationService.Navigate(new Uri("/View/Turnstile.xaml", UriKind.Relative));
                break;

            case 1:
                this.navigationService.Navigate(new Uri("/View/TurnstileFeather.xaml", UriKind.Relative));
                break;

            case 2:
                this.navigationService.Navigate(new Uri("/View/Continuum.xaml", UriKind.Relative));
                break;

            case 3:
                //slide right
                this.navigationService.Navigate(new Uri("/View/SlideRight.xaml", UriKind.Relative));
                break;

        }
    }
}

And we are done!

Couple of things to watch out for when implementing the page transitions

  1. Make sure that you have the correct base url in you WMAppManifest.xml.
    It should look something like this

    <Tasks>
          <DefaultTask  Name ="_default" NavigationPage="View/MainPage.xaml"/>
        </Tasks>
    

    Even if you have a sub folder which contains your Views

  2. If you have already overriden the OnBackKeyPress handler remember to call the base implementation

If you have created transitions and happy to share or have ideas for ones you would like to see then please contact me.

Who ate all the pies!!

My current project has taken me on an interesting journey of late and so I thought that it would be helpful to share with you some of my experiences and of course some code. I have been taking a look into charting on WP7 there is a good round up here of the different toolkits that are available. I also started out using the Visifire charts, they do pretty much everything that you need. Next, I started playing with the Data Visualisation bits from David Anson. The change over from Visifire to the new charts was rather painless, the main changes I had to make here were; the updates to the palettes used by the chart; and some differences on how the bindings work. For this first chart I was using a line series. The next chart I needed to use was chart that uses a Pie Series layout and this was surprisingly straight forward to get some instant results, but I wanted more from those pies!

So, if you have tried to make your pies more interesting then you will know that they work differently in comparison to the other charting series, its also rather tricky to get those pies looking good. So I went on a search to find out what other folks have been doing. First up I found that Pete Brown has a couple of great post on style and template pies using overlays and another interesting one about using gradients. Unfortunately it does have a number of limitations, so David came up with a yummy pie. Adding these simple gradient brushes

to your chart can really make a visual impact and make you pie look more appertising. So, those pies were good but now I have taste for them and I want more. Luckily, Bea Costa has a great custom chart control that supports labels on your pies. The Legend, can still be used if you want it, but in my current implementation it’s not being used.

With some quick tweaks to the positioning of the labels to better suit a smaller sized screen, a change to the orientation of the labels, a new  chart style and template for Bea’s control. I was able to create some lovely looking pies this time around with labels. I wanted to try out the experience around the labels on 2 levels; firstly I wanted to make the values more apparent as the legend in portait mode is ok but not great; secondly I wanted to provide a level of interaction for the user so that they can select a particular segment of the pie.

Now there are a couple of caveats here and that is I am only supporting portrait orientation, there are templates for portrait and landscape however there needs to be some more work done before this is can be moved into the WP7Contrib. I am actually wondering if the label experience is in general just bad when in landscape and that this we should fall back to a simple Legend. Not sure yet, I will try out some ideas and post an update on my findings. The final caveat which applies to both charts is that the popup is not useable for touch as it is displayed under the digit. I will continue to try and improve this.

Stop talking and show me the pies!! Its Friday which is pie day

Labeled Pie

 
Regular Pies

 
You can get a cut of the code here, interested in your thoughts and comments especially around the Ux when in landscape mode. Enjoy those pies!!
 

WP7 Contrib – When messaging becomes messy and services shine

In a previous post I introduced you to the Last Message Replay Messenger, in this post I wanted to dig into something that happened recently where I needed to provided the ability in the application for the user to add an item to a favourites list. Ok so fairly straight forwards, however there was a slight twist. Not only can the user add items to their favourites from a list but they can also add an item to their favourites list from a number of different places in the application. Each view has a different VM and we don’t want to chain the VM’s together as then they know about each other; we also don’t want to use the VM Locator from the Xaml and call the same relay command to perform the action; so on the surface this looks like a job for a messenger :-

  1. Define the Message which wraps up the data
  2. Add the IMessenger interface as a parameter in the VM constructor
  3. Register the IMessenger interface with the Last Message Replay Messenger
  4. In the originator register the type of message data your interested in with the Notification Message Action
  5. In the VM which is interested in the message register for the Message defined in step 1
  6. Provide a method that deals with the received messages and sets up the data context of the View

Now this works just fine when I want to pass data to disconnected lazy loading VM’s but I got into trouble when it came to stashing this content. The main reason is that it comes down to a level of responsibility which results in the question of who owns the data ? and who is responsible for storing the data ?

What I ended up with was a collection of favourites that were being managed by each VM that required their Views to have the ability; add to the favourites list and then fire a message broadcasting that here is the new favourite item which needs to be added into the favourites collection. Cool!

So all is cool now? Well sure until it comes to building out the persistence mechanism using the override Activate and DeActive methods that the VM Base provides us with in order to store the data. My next move was then to start changing the data inside of the Message to a collection of the same type, but this solution means that I now pass around a reference pointer to the collection in the message and each VM is then responsible for adding new items. The Favourites VM is then inherently responsible for persisting the collection. Ok so that gets us closer. Unfortunately, the Favourites Page and VM are not primaries in the user journey through the app therefore, there is a high potential that the user will not have viewed the Favourites Page resulting the Favourites VM not being instantiated and now things start to get sticky again….

At this point its time for a brew…. I could continue trying to bend the message pattern to fit our needs but its generating a large amount of friction when we try and push. This is where using a service makes far more sense. Now, if you chat to Ollie he will say well this is all about “ask don’t tell, Rich”. Therefore, moving to a more service style pattern similar to the one used in the service layer for our Apps results in those VM’s which need to use the favourites service have this injected during startup via the bootstrapper. Unlike our current situation where each VM has to register for the message. This gets us back into check with a single responsibility pattern. As the favourites service is now responsible for anything to do with favourites cleaning up the implementation code in the VM’s wanting to use the service. Sweet!

Now I really like this pattern as its super simple to implement and by taking advantage of IStorage and IStorageService which can be found in the WP7C not only do we have a simple pattern for sharing data and operating on that data, we also get the ability to stash this content into Isolated Storage.

The best way for me to show this off is to do a sample, so I am going to build on the sample from the previous post, its also in the spikes directory on Codeplex. What we are going to add to this is a favourites page, wired up to a Favourites VM, and a favourites service that has the ability for our user to do an add to favourites from the list (Main VM)and an add to favourites from the details page (Child VM).

First, up we need to create an interface, in my case its called IFavouriteSearch and it going to provide a service to retrieve the current collection of favourites, add a new favourite, query to see if the service already contains a particular favourite and also remove a favourite from the collection.

using ServiceStyleRatherThanMessengerStyle.Model;

using WP7Contrib.Collections;

/// <summary>
/// The favourites service contract.
/// </summary>
public interface IFavouritesService
{
        #region Properties

        /// <summary>
        /// Gets Favourites.
        /// </summary>
        ReadOnlyObservableCollection<Person> Favourites { get; }

        #endregion

        #region Public Methods

        /// <summary>
        /// The add.
        /// </summary>
        /// <param name="person">
        /// The currently selected person.
        /// </param>
        void Add(Person person);

        /// <summary>
        /// The is a favourite.
        /// </summary>
        /// <param name="person">
        /// The person.
        /// </param>
        /// <returns>
        /// The is a favourite.
        /// </returns>
        bool IsAFavourite(Person person);

        /// <summary>
        /// The remove favoutite.
        /// </summary>
        /// <param name="person">
        /// The person.
        /// </param>
        void RemoveFavourite(Person person);

        #endregion
}

That’s the service defined.

Next up we need to define a concrete class called the Favourite Service which implements the interface, the important part to remember here is that we want to stash the collection to isolated storage in order to persist the selected favourites between sessions. In order to do this we can simply pass into the constructor the IStorageService interface, if you wanted to use the logging parts of WP7C then you can added this into the constructor parameter list.

public FavouritesService(IStorageService storageService, ILog log)
{
   this.storageService = storageService;
   this.log = log;
}

So this is the cool part, when we expose the favourites collection all we need to do is work out if we are rehydrating the collection for the first time from Isolated Storage and load up the collection in ISO, otherwise we new up a collection of the required type. Each piece of content that is stored into ISO has its own key, in my case its called favourites and its used as the Unique ID to retrieve the specified content. The code to Load from Storage is boiler plate and done once it’s a rinse and repeat style pattern.

/// <summary>
/// Gets Favourites.
/// </summary>
public ReadOnlyObservableCollection<Person> Favourites
{
   get
   {
      if (!this.loaded)
      {
         this.LoadFromStorage();
      }

       return new ReadOnlyObservableCollection<Person>(this.favourites);
   }
}

The management methods that operate on the collection we build out as normal and then decorate this code with the storage calls. These are rather easy to remember; once the collection has been updated then we make a call to write the list into ISO associated with our Unique ID, then we flush the storage buffer.

/// <summary>
/// Adds a person to the favourites.
/// </summary>
/// <param name="person">
/// The currently selected person.
/// </param>
public void Add(Person person)
{
   if (person == null)
   {
      return;
   }

   if (!this.loaded)
   {
      this.LoadFromStorage();
   }

   if (this.favourites.Contains(person))
   {
      return;
   }

   this.favourites.Add(person);
   this.storage.Write(StorageKey, this.favourites.ToList());
   this.storage.Flush();
}

/// <summary>
/// The is a favourite.
/// </summary>
/// <param name="person">
/// The person.
/// </param>
/// <returns>
/// Returns true if the person is a favourite.
/// </returns>
public bool IsAFavourite(Person person)
{
   if (person == null)
   {
      return false;
   }

   if (!this.loaded)
   {
      this.LoadFromStorage();
   }

   return this.favourites.Contains(person);
}

/// <summary>
/// The remove favoutite.
/// </summary>
/// <param name="person">
/// The persoh.
/// </param>
public void RemoveFavourite(Person person)
{
   if (person == null) 
   {
      return;
   }

   if (!this.loaded)
   {
      this.LoadFromStorage();
   }

   if (!this.favourites.Contains(person))
   {
      return;
   }

   this.favourites.Remove(persoh);
   this.storage.Write(StorageKey, this.favourites);
   this.storage.Flush();
}

Lets now take a look at the Load From Storage method.

/// <summary>
/// The load from storage.
/// </summary>
private void LoadFromStorage()
{
   if (this.loaded)
   {
      return;
   }

   lock (this.sync)
   {
      if (this.loaded)
      {
         return;
      }

      this.favourites = new ObservableCollection<Person>();
      this.storage = this.storageService.OpenPersistent(StorageKey);

      var favs = this.storage.Read<List<Person>>(StorageKey);
      if (favs == null || favs.Count == 0)
      {
         this.log.Write("FavouritesService: No favourites");
      }
      else
      {
         foreach (Person fav in favs)
         {
              this.log.Write("FavouritesService: Loading Person, hash code - " + fav.GetHashCode());
              this.favourites.Add(fav);
         }
     }

      this.loaded = true;
   }
}

When we need to read the collection we use the Storage service to setup the storage mechanism once this has been done happy days simply call the Read method telling what type is being rehydrated using the specified Unique key that was defined earlier. Iterate over what comes out and add it to our collection.

Now we need to be able to use the service so we head over to the bootstrapper and crank out some register and resolve calls for the service.

this.Container.Register<ILogManager>(c => new LoggingService("LastReplayMessenger"));

this.Container.Register<ILog>(c => this.Container.Resolve<ILogManager>());

var assemblies = new List<Assembly> { this.GetType().Assembly, typeof(BaseModel).Assembly };

this.Container.Register<IStorageService>(c => new StorageService(c.Resolve<ILog>(), assemblies));

this.Container.Register<IFavouritesService>(
c => new FavouritesService(c.Resolve<IStorageService>(), c.Resolve<ILog>()));

And that’s our service registered and resolved, our next step is to inject the favourite service into the VM’s that are going to be using it.

this.Container.Register(
c =>
new MainViewModel(
c.Resolve<INavigationService>(),
c.Resolve<IMessenger>(),
c.Resolve<ILog>(),
c.Resolve<IFavouritesService>()));

this.Container.Register(
c =>
new ChildViewModel(
c.Resolve<INavigationService>(),
c.Resolve<IMessenger>(),
c.Resolve<ILog>(),
c.Resolve<IFavouritesService>()));

A common scenario is that we have a View which provides an experience that allows the user to add items via a list. In my case I choose a context menu which was added to the data template used by the list box. In order to do this I created a Relay Command and wired this up to the context menu from the toolkit in the data template. There are two implementations that we need to implement here first we need to be able to trigger a command from inside the data template of the listbox.

/// <summary>
/// The select add to favourites command.
/// </summary>
private RelayCommand<Person> selectAddToFavouritesCommand;

/// <summary>
/// Gets SelectAddToFavouritesCommand.
/// </summary>
public RelayCommand<Person> SelectAddToFavouritesCommand
{
   get
   {
      return this.selectAddToFavouritesCommand ??
      (this.selectAddToFavouritesCommand = new RelayCommand<Person>(this.ExecuteAddToFavouritesCommand));
   }

   private set
   {
      this.selectAddToFavouritesCommand = value;
   }
}

/// <summary>
/// The execute add to favourites command.
/// </summary>
/// <param name="person">
/// The person.
/// </param>
private void ExecuteAddToFavouritesCommand(Person person)
{
   this.favouritesService.Add(person);
}
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="add to favourites"
Command="{Binding MainViewModel.SelectAddToFavouritesCommand, Source={StaticResource Locator}}"
CommandParameter="{Binding .}" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>

And the other implementation is from an app bar button.

/// <summary>
/// The execute add to favourites command.
/// </summary>
private void ExecuteAddToFavouritesCommand()
{
   this.favouritesService.Add(this.CurrentlySelectedPerson);
   this.NavigationService.Navigate(new Uri("/View/FavouritesPage.xaml", UriKind.Relative));
}
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True"
IsMenuEnabled="True">
<shell:ApplicationBarIconButton x:Name="AddToFavourites"
IconUri="/resources/icons/appbar.favs.addto.rest.png"
Text="AddToFavourites" />
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>

<i:Interaction.Behaviors>
<Behaviors:ApplicationBarIconButtonCommand TextKey="AddToFavourites"
CommandBinding="{Binding SelectAddToFavouritesCommand}" />
</i:Interaction.Behaviors>

Lets just quickly circle back, what we have done thus far is implement the required add to favourites functionality, but ultimately we also want to allow the user to view their favourites so next we need to create the page and the favourites VM remembering to add the new VM to the VM Locator.

The favourites VM.

/// <summary>
/// The favourites view model.
/// </summary>
public class FavouritesViewModel : ViewModelBaseWp7
{
    #region Constants and Fields

    /// <summary>
    /// The favourites service.
    /// </summary>
    private readonly IFavouritesService favouritesService;

    /// <summary>
    /// The currently selected person.
    /// </summary>
    private Person currentlySelectedPerson;

    #endregion

    #region Constructors and Destructors

    /// <summary>
    /// Initializes a new instance of the <see cref="FavouritesViewModel"/> class.
    /// </summary>
    /// <param name="navigationService">
    /// The navigation service.
    /// </param>
    /// <param name="messenger">
    /// The messenger.
    /// </param>
    /// <param name="log">
    /// The log.
    /// </param>
    /// <param name="favouritesService">
    /// The favourites service.
    /// </param>
    public FavouritesViewModel(
        INavigationService navigationService, IMessenger messenger, ILog log, IFavouritesService favouritesService)
        : base(navigationService, messenger, log)
    {
        this.favouritesService = favouritesService;

        ThreadPool.QueueUserWorkItem(
            state => { this.MessengerInstance.Register<SelectedPersonMessage>(this, this.OnReceiveMessage); });
    }

    #endregion

    /// <summary>
    /// Gets CurrentlySelectedCurrentlySelectedPerson.
    /// </summary>
    public Person CurrentlySelectedPerson
    {
        get
        {
            return this.currentlySelectedPerson;
        }

        private set
        {
            this.SetPropertyAndNotify(ref this.currentlySelectedPerson, value, "CurrentlySelectedPerson");
        }
    }


    public ReadOnlyObservableCollection<Person> Favourites
    {
        get
        {
            return this.favouritesService.Favourites;
        }
    }

    #region Methods

    private void OnReceiveMessage(SelectedPersonMessage obj)
    {
        if (obj == null)
        {
            return;
        }

        if (obj.Person == null)
        {
            return;
        }

        this.CurrentlySelectedPerson = obj.Person;
    }

    /// <summary>
    /// The is being activated.
    /// </summary>
    /// <param name="storage">
    /// The storage.
    /// </param>
    protected override void IsBeingActivated(IStorage storage)
    {
    }

    /// <summary>
    /// The is being deactivated.
    /// </summary>
    /// <param name="storage">
    /// The storage.
    /// </param>
    protected override void IsBeingDeactivated(IStorage storage)
    {
    }

    #endregion
}

And the favourites page which has a listbox data bound to the favourites collection exposed by the VM.

<Grid x:Name="ContentPanel"
Grid.Row="1"
Margin="12,0,12,0">
<ListBox ItemsSource="{Binding Path=Favourites}"
SelectedItem="{Binding Path=CurrentlySelectedPerson}"
ItemTemplate="{StaticResource PersonsDataTemplate}"
ItemContainerStyle="{StaticResource ListBoxItemStyle1}" />
</Grid>

And we are done!

One thing that I did add here is the Last Replay Message Messenger and data binding to the selected item in the listbox so that I can highlight the newly added favourite.

A quick recap on what happened

  1. Create the interface for the service and expose what you need usually a collection and some management methods for managing the data
  2. Create the concrete implementation adding in the IStorageService into the constructor
  3. In the concrete add logic to rehydrate and stash your data
  4. Update the constructor on the VM’s that need to have the add to favourites functionality
  5. In the Bootstrapper register the new service and Resolve them in the VM’s
  6. Create relay commands in the VM and View to trigger the actions
  7. Create the favourites page and VM
  8. Update the Bootstrapper and VM Locator with the new VM
  9. Expose a property for the collection so that it can be bound to in the View
  10. [Optional] use the Last Replay Message to inform the favourites VM about the currently selected person

What is very interesting about all this is that we so often when using a framework get familiar with a certain technique and this becomes fashionable and we try to use it everywhere and there is nothing wrong with trying out new ways of doing something. However, there also has to be a realisation that when we start getting friction trying to bend the framework api to do something that it was not really meant for its time to use something solves the problem better.

Interested in your comments and you can find the code up on codeplex.

WP7 Contrib – the last messenger

As you may already be aware the WP7C uses MVVM Light as its preferred MVVM framework. Laurent has a great implementation of a Mediator style pattern that he has aptly name the Messenger. What I really like about this is the simplicity when it comes to implementing the baked in messages and how you can extend the IMessenger interface that Laurent has included in MVVM Light. In general these generic messages cater for the majority of problems. However, there is a case that is not particularly well catered for. What follows is focused on WP7 however, this messenger component could be recompiled under your favourite SL build and used in your MVVM Light application today.

Before we start to roll you are going to make sure you have all the bits installed

WP7 Dev tools ISO download thanks JaimeR

MVVM Light Toolkit

WP7 Contrib

Now if you are using some sort of DI component, at the moment my favourite is funq (Ninject will always have a place in my heart) you may have found yourself in a situation where by you want to pass data from one VM to another, however the VM you want to pass the data to has not yet been created. There are various ways around this like not using DI and newing up all your VM during start-up so that this is no longer an issue. But, remember we are running under WP7 and performance is never going to be what it’s like in the browser. We also want to take advantage of DI and all the goodness that it brings to the party.

Which came first, the chicken or the egg ??

An inherent problem with using Silverlight navigation and DI and having your VM’s lazily loaded. When you navigate to a page its not until this moment in time that your VM is constructed, therefore we hit this timing problem where the VM that is loaded up and trying to send a message to a VM which has yet to be loaded. What we first started out with was an implementation that was not so polished in that we would have a Register and Send Message being defined in the VM making the call; a Register Message defined in the receiving VM; and a callback Message in the receiving VM.

The way in which this works would be something like :-

  1. VM SearchPeople Registers for Message CurrentlySelectedPerson
  2. In response to an interaction in the View (i.e. selecting an item in a list box). The associated VM SearchPeople Sends Message CurrentlySelectedPerson from within a INPC Property
  3. In response to an interaction in the View (i.e. tapping an item in a list box). The associated VM SearchPeople ‘s RelayCommand navigates to a new page Person Details
  4. VM Person Details is constructed by our DI framework
  5. VM Person Details constructor Registers for the Message CurrentlySelectedPerson
  6. VM Person Details constructor fires a CallBack for the MessageCurrentlySelectedPerson
  7. VM SearchPeople received the Message CurrentlySelectedPerson
  8. VM SearchPeople Send the Message CurrentlySelectedPerson
  9. VM PersonDetails received the Message CurrentlySelectedPerson

This mechanism has to deal with the timing issue of the second VM not being loaded before the message is sent from the first, we end up in a situation where the first message never works and the subsequent messages always work. Therefore, by providing a callback in the second and sending the message from here to the first VM we solve the problem, but its not as elegant as it could be. The main issue here is that we are forced to send our messages twice due to the fact that our recipient VM has yet to be created and we need to give it a poke.

What becomes apparent is that the callback mechanism is not built for this type of work and we need a more structured and direct messaging mechanism. I had a chat with Ollie and he came up with a great messaging implementation. The rest of this post is concerned with how to use this Replay Messenger in your app, Ollie has a great post coming where he is going to go into more detailed post on the implementation details.

Laurent has provided an interface called IMessenger which provides developers with the ability to extend the and create our own Messages, nice… Let’s make a start on building out a simple implementation. If you have all the bits installed lets make a start. First off what is this app we are going to build, well is a simple app which has some sort of people list and we can select a person from the list and navigate to a more detailed page. Not the most exciting of apps but I want to keep the context fairly striaght forward so that we can concentrate on the problem and the solution rather than being distracted by other stuff. Saying that you are going too meet some other interface from WP7Contrib, ILogManager, ILog and INavigation Service. Over on the right you can see an screen shot showing the strcuture of the sample which can be found in the Spikes dir of the WP7Contrib.

My intentions below are not to walk you through every step we have some planned detailed posts and maybe even some screencasts to illustrate this points, therefore I am assumming that you know about the message classes availavble to you in MVVM Light Messaging and I am also assuming that you understand how to uses a DI framework.

Over on the right there is a screen grab of the solution if you want to fire this up then you can find it in the Spikes dir of the WP7Contrib. I have a model class called Person this is going to hold our data;2 pages main page and child page; 2 corresponding View Models main VM and child VM; in messages I have a base message and something called the Selected Person Message; a custom Base VM for WP7 which subclasses the MVVM Light VM Base; and finally I have a BootStrapper for my DI bits.

So first off what we need to do is take a look at the Selected Person Message as this is the message which is a wrapper for our data that we want to pass from the Main VM to the Child VM.

namespace ReplayLastMessageMessenger.ViewModel.Messages
{
    using System;

    using ReplayLastMessageMessenger.Model;

    /// <summary>
    /// The currently selected search result message.
    /// </summary>
    public class SelectedPersonMessage : BaseMessage
    {
        #region Constants and Fields

        /// <summary>
        /// The person.
        /// </summary>
        private readonly Person person;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="SelectedPersonMessage"/> class.
        /// </summary>
        /// <param name="person">
        /// The person.
        /// </param>
        public SelectedPersonMessage(Person person)
        {
            this.person = person;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SelectedPersonMessage"/> class.
        /// </summary>
        /// <param name="exception">
        /// The exception.
        /// </param>
        public SelectedPersonMessage(Exception exception)
        {
            this.Exception = exception;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets person.
        /// </summary>
        public Person Person
        {
            get
            {
                return this.person;
            }
        }

        #endregion
    }
}

The code above is boiler plate making the implementation clean and repeatable, the code above is the message that we use for passing Property data between our VM’s.

That’s the message built.

Remember, what we have in our view is a list of items, and in our case a list of people and when you select an item from the list we navigate from this page to a details page, and we do this by sending a message that contains the data of the currently selected item from the list.

/// <summary>
/// Gets or sets CurrentlySelectedPerson.
/// </summary>
public Person CurrentlySelectedPerson
{
    get
    {
        return this.currentlySelectedPerson;
    }

    set
    {
        this.SetPropertyAndNotify(ref this.currentlySelectedPerson, value, "CurrentlySelectedPerson");
        this.NavigationService.Navigate(new Uri("/View/ChildPage.xaml", UriKind.Relative));
        this.MessengerInstance.Send(new SelectedPersonMessage(this.currentlySelectedPerson));
    }
}

Note, in the above code the Messenger is only responsible for sending message, its the Navigation Service that is responsible for the navigation from the list page to the details page and the details page displays the details of the data item selected from the list, therefore the Child VM will need to know the currently selected person. I will cover off the Navigation Service interface in a future post.

In order to do this we need to inject the IMessenger into each VM from our bootstrapper. I am using funq for this so the code below is specific to funq however it’s the same drill register your wire ups with the container and then resolve them to an interface, This will provide a way of firing Registering and Sending those Currently Selected Person messages.

public class BootStrapper : IDisposable
{
    #region Constants and Fields

    /// <summary>
    /// The disposed.
    /// </summary>
    private bool disposed;

    #endregion

    #region Constructors and Destructors

    /// <summary>
    /// Initializes a new instance of the <see cref="BootStrapper"/> class.
    /// </summary>
    public BootStrapper()
    {
        this.Container = new Container();

        this.ConfigureContainer();
    }

    #endregion

    #region Properties

    /// <summary>
    /// Gets Container.
    /// </summary>
    public Container Container { get; private set; }

    #endregion

    #region Implemented Interfaces

    #region IDisposable

    /// <summary>
    /// The dispose.
    /// </summary>
    public void Dispose()
    {
        if (this.Container != null)
        {
            this.Container.Dispose();
            this.Container = null;
        }
    }

    #endregion

    #endregion

    #region Methods

    /// <summary>
    /// The configure container.
    /// </summary>
    private void ConfigureContainer()
    {
        this.Container.Register<ILogManager>(c => new LoggingService());

        this.Container.Register<ILog>(c => this.Container.Resolve<ILogManager>());

        this.Container.Register<IMessenger>(c => new LastMessageReplayMessenger());

        this.Container.Register<INavigationService>(
            c => new ApplicationFrameNavigationService(((App)Application.Current).RootFrame));

        this.Container.Register(
            c => new MainViewModel(c.Resolve<INavigationService>(), c.Resolve<IMessenger>(), c.Resolve<ILog>()));

        this.Container.Register(
            c => new ChildViewModel(c.Resolve<INavigationService>(), c.Resolve<IMessenger>(), c.Resolve<ILog>()));
    }

    #endregion
}

There are a couple of interfaces here that I am injecting into my VM’s these include the Navigation Service, the log manager and the log all of which we will talk about in future posts.

Again, Laurent has done a great job by providing a property in the View Model Base called Messenger Instance which returns the instance of the messenger we injected in our bootstrapper, nice. There is a small nugget here as well to help with performance, as the registration of the message does not need to happen on the UI thread we can wrap this up like so.

The Main VM looks like this.

public MainViewModel(INavigationService navigationService, IMessenger messenger, ILog log)
    : base(navigationService, messenger, log)
{
    ThreadPool.QueueUserWorkItem(state =>
    {
        // messaging
        this.MessengerInstance.Register<NotificationMessageAction<Person>>(
            this, message => message.Execute(this.CurrentlySelectedPerson));
    });
}

Now in the constructor of the Child VM its far sweeter code instead of the crufty callback and force a message in order to get the data we simply register for the replay message we are interested in, and provide a method to deal with the received message.

public ChildViewModel(INavigationService navigationService, IMessenger messenger, ILog log)
    : base(navigationService, messenger, log)
{
    ThreadPool.QueueUserWorkItem(state =>
    {
        this.MessengerInstance.Register<SelectedPersonMessage>(this, this.OnReceiveMessage);
    });
}

The Xaml in the Main View looks like this.

<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel"
        Grid.Row="1"
        Margin="12,0,12,0">
    <ListBox ItemsSource="{Binding Path=Persons}"
                SelectedItem="{Binding Path=CurrentlySelectedPerson, Mode=TwoWay}"
                ItemTemplate="{StaticResource PersonsDataTemplate}" />
</Grid>

The Xaml in the Child View looks like this.

<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel"
        Grid.Row="1"
        Margin="12,0,12,0">
    <Grid.RowDefinitions>
        <RowDefinition Height="90" />
        <RowDefinition Height="513" />
    </Grid.RowDefinitions>
    <StackPanel Orientation="Vertical">
        <TextBlock Text="{Binding CurrentlySelectedPerson.LastName}"
                    FontFamily="{StaticResource PhoneFontFamilySemiLight}"
                    FontSize="{StaticResource PhoneFontSizeMediumLarge}" />
        <TextBlock Text="{Binding CurrentlySelectedPerson.FirstName}"
                    FontFamily="{StaticResource PhoneFontFamilySemiLight}"
                    FontSize="{StaticResource PhoneFontSizeMedium}" />
    </StackPanel>
    <Border Grid.Row="1"
            BorderThickness="2">
        <Image Source="{Binding CurrentlySelectedPerson.ProfileImage}" />
    </Border>
</Grid>
</Grid>


Just to recap our steps were :-

  1. Define the Message which wraps up the data
  2. Add the IMessenger interface as a parameter in the VM constructor
  3. Register the IMessenger interface with the Last Message Replay Messenger
  4. In the originator register the type of message data you’re interested in with the Notification Message Action
  5. In the VM which is interested in the message register for the Message defined in step 1
  6. Provide a method that deals with the received messages and setups up the data context of the View

You can find out more information on the WP7Contrib and find out what people are saying on twitter #WP7Contrib.

As i mentioned at the start if you are already using MVVM Light today then you can take advantage of the Last Replay Message. Ollie is going to follow up with a more detail post on the implementation details.

WP7 Contrib – Customising the DateTime Picker

As you may already be aware there are two controls in the WP7 toolkit that provide the standard interactions and UI for selecting time and a date. Personally these are 2 of my favourite controls mainly due to the transitions and simple UI. However….. What happens when we are building an application that needs you to enter credit card details ? Or you only want a subset of the provided controls i,e, a Month and a Year ? Unfortunately at the moment AFAIK  there is no way of doing this with the provided controls, its just not possible using Xaml either via the Style or the Template. We need to dig in a little deeper and find out what controls are actually powering these pickers. Well you don’t have to go too far before you find something called the Looping Selector control, the control provides an Item Template so that we can if we want add our own Data Template if so desired.

So why would you want to do this ? Well for us we need to provide an experience where the user of the app is prompted to enter in their credit card details. It seems only sensible to use the standard UI metaphor for picking a Date or a Time on WP7. As I found out this is just not possible and a level of customisation is required in order to achieve the interactions that we want along with the right experience.

This problem can be divided into two main pieces; data we will need to provided some subclassed data sources for day, month and year; UI we need to change the looping selectors visibility and do some work around hooking up the controls with data.

In the WP7 Contrib View project you can locate the DateTime Picker folder where the data sources are defined to support the picker. The main thing that we here is to reuse the same data source classes that are defined in the toolkit however we have changed the accessor to be public so that we can seem where we are using the control. The code below is here for completion and your viewing pleasure.

The Day DataSource

namespace WP7Contrib.View.Controls.DateTimePicker
{
    using System;

    public class DayDataSource : DataSource
    {
        // Methods
        /// <summary>
        /// Gets the relative to.
        /// </summary>
        /// <param name="relativeDate">The relative date.</param>
        /// <param name="delta">The delta.</param>
        /// <returns></returns>
        protected override DateTime? GetRelativeTo(DateTime relativeDate, int delta)
        {
            int num = DateTime.DaysInMonth(relativeDate.Year, relativeDate.Month);
            return new DateTime(relativeDate.Year, relativeDate.Month, ((((num + relativeDate.Day) - 1) + delta) % num) + 1);
        }
    }
}

The Month DataSource

namespace WP7Contrib.View.Controls.DateTimePicker
{
    using System;

    public class MonthDataSource : DataSource
    {
        // Methods
        /// <summary>
        /// Gets the relative to.
        /// </summary>
        /// <param name="relativeDate">The relative date.</param>
        /// <param name="delta">The delta.</param>
        /// <returns></returns>
        protected override DateTime? GetRelativeTo(DateTime relativeDate, int delta)
        {
            int num = 12;
            int month = ((((num + relativeDate.Month) - 1) + delta) % num) + 1;
            return new DateTime(relativeDate.Year, month, Math.Min(relativeDate.Day, DateTime.DaysInMonth(relativeDate.Year, month)));
        }
    }
}

The Year DataSource

namespace WP7Contrib.View.Controls.DateTimePicker
{
    using System;

    public class YearDataSource : DataSource
    {
        // Methods
        /// <summary>
        /// Gets the relative to.
        /// </summary>
        /// <param name="relativeDate">The relative date.</param>
        /// <param name="delta">The delta.</param>
        /// <returns></returns>
        protected override DateTime? GetRelativeTo(DateTime relativeDate, int delta)
        {
            if ((0x641 == relativeDate.Year) || (0xbb8 == relativeDate.Year))
            {
                return null;
            }
            int year = relativeDate.Year + delta;
            return new DateTime(year, relativeDate.Month, Math.Min(relativeDate.Day, DateTime.DaysInMonth(year, relativeDate.Month)));
        }
    }
}

Now that we have redefined these datasources we want to use in our customised implementation the next part is to take a look at the guts of the Xaml that is being used to compose the Picker as we mentioned earlier on there is the LoopingSelector that can be found in the Primitives namespace. This control is rather nice and does what it says on the tin, by providing a gambling machine style interaction. If you take a look at the Xaml defined in the DateTimePicker.xaml this is essentially what we need, so again this is pretty much a copy and paste job. I created a new user control called MonthYearPicker.xaml and stuffed the Xaml in here. The only changes that we need to make in the Xaml is to change the visibility of the looping selector that you don’t want to present to the user, in my case this was the day. Now we could do some more sophisticated stuff here, like provide an attached Dependency Property to control the visibility of the selector this is on the list so watch this space, but if you can think of any others shout.

<!-- LoopingSelectors -->
        <Grid
            Grid.Row="2"
            HorizontalAlignment="Center">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Primitives:LoopingSelector
                x:Name="SecondarySelector"
                Grid.Column="0"
                Width="148"
                ItemSize="148,148"
                ItemMargin="6">
                <Primitives:LoopingSelector.ItemTemplate>
                    <DataTemplate>
                        <StackPanel
                            HorizontalAlignment="Left"
                            VerticalAlignment="Bottom"
                            Margin="6">
                            <TextBlock
                                Text="{Binding MonthNumber}"
                                FontSize="54"
                                FontFamily="{StaticResource PhoneFontFamilySemiBold}"
                                Margin="0,-8"/>
                            <TextBlock
                                Text="{Binding MonthName}"
                                FontSize="20"
                                FontFamily="{StaticResource PhoneFontFamilyNormal}"
                                Foreground="{StaticResource PhoneSubtleBrush}"
                                Margin="0,-2"/>
                        </StackPanel>
                    </DataTemplate>
                </Primitives:LoopingSelector.ItemTemplate>
            </Primitives:LoopingSelector>
            <Primitives:LoopingSelector
                x:Name="TertiarySelector"
                Grid.Column="1"
                Width="0"
                ItemSize="148,148"
                ItemMargin="6" Foreground="{x:Null}" Visibility="Collapsed">
                <Primitives:LoopingSelector.ItemTemplate>
                    <DataTemplate>
                        <StackPanel
                            HorizontalAlignment="Left"
                            VerticalAlignment="Bottom"
                            Margin="6">
                            <TextBlock
                                Text="{Binding DayNumber}"
                                FontSize="54"
                                FontFamily="{StaticResource PhoneFontFamilySemiBold}"
                                Margin="0,-8"/>
                            <TextBlock
                                Text="{Binding DayName}"
                                FontSize="20"
                                FontFamily="{StaticResource PhoneFontFamilyNormal}"
                                Foreground="{StaticResource PhoneSubtleBrush}"
                                Margin="0,-2"/>
                        </StackPanel>
                    </DataTemplate>
                </Primitives:LoopingSelector.ItemTemplate>
            </Primitives:LoopingSelector>
            <Primitives:LoopingSelector
                Grid.Column="2"
                x:Name="PrimarySelector"
                Width="148"
                ItemSize="148,148"
                ItemMargin="6">
                <Primitives:LoopingSelector.ItemTemplate>
                    <DataTemplate>
                        <StackPanel
                            HorizontalAlignment="Left"
                            VerticalAlignment="Bottom"
                            Margin="6">
                            <TextBlock
                                Text="{Binding YearNumber}"
                                FontSize="54"
                                FontFamily="{StaticResource PhoneFontFamilySemiBold}"
                                Margin="0,-8"/>
                            <TextBlock
                                Text=" "
                                FontSize="20"
                                FontFamily="{StaticResource PhoneFontFamilyNormal}"
                                Foreground="{StaticResource PhoneSubtleBrush}"
                                Margin="0,-2"/>
                        </StackPanel>
                    </DataTemplate>
                </Primitives:LoopingSelector.ItemTemplate>
            </Primitives:LoopingSelector>
        </Grid>

The final piece of the puzzle is the wire up, you maybe thinking why can’t you remove the looping selectors that you don’t want ? Well I thought that same thing, however its does not seem possible as the LoopingSelector wants 3 parts to be initialised; a Primary Part / Selector; a Secondary Part / Selector; and a Tertiary Part / Selector. Therefore we have to define all of the selectors in the Xaml. Now that we have that worked out we need to bring over some of the methods from the codebehind the picker from the toolkit.

Initialisation code

public MonthYearPicker()
        {
            this.InitializeComponent();
            this.PrimarySelector.DataSource = new YearDataSource();
            this.SecondarySelector.DataSource = new MonthDataSource();
            this.TertiarySelector.DataSource = new DayDataSource();

            ((DataSource)this.PrimarySelector.DataSource).AltSelectionChanged += this.HandleAltDataSourceSelectionChanged;
            ((DataSource)this.SecondarySelector.DataSource).AltSelectionChanged += this.HandleAltDataSourceSelectionChanged;
            ((DataSource)this.TertiarySelector.DataSource).AltSelectionChanged += this.HandleAltDataSourceSelectionChanged;

            this.InitializeDateTimePickerPage(this.PrimarySelector, this.SecondarySelector, this.TertiarySelector);
        }

Composition of the parts for the picker

        /// <summary>
        /// Gets a sequence of LoopingSelector parts ordered according to culture string for date/time formatting.
        /// </summary>
        /// <returns>
        /// LoopingSelectors ordered by culture-specific priority.
        /// </returns>
        protected override IEnumerable<LoopingSelector> GetSelectorsOrderedByCulturePattern()
        {
            return GetSelectorsOrderedByCulturePattern(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.ToUpperInvariant(), new char[] { 'Y', 'M', 'D' }, new LoopingSelector[] { this.PrimarySelector, this.SecondarySelector, this.TertiarySelector });
        }

Handles the alt data source selection changed.

        /// <summary>
        /// Handles the alt data source selection changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Controls.SelectionChangedEventArgs"/> instance containing the event data.</param>
        private void HandleAltDataSourceSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DataSource source = (DataSource)sender;
            if (source is YearDataSource)
            {
                // Set the year part of the value
                this.PrimarySelector.DataSource.SelectedItem = source.SelectedItem;
                if (source.SelectedItem != null && this.Value.HasValue)
                {
                    this.Value = new DateTime(
                        ((DateTimeWrapper)source.SelectedItem).DateTime.Year, this.Value.Value.Month, 1);
                }
            }
            else if (source is MonthDataSource)
            {
                // Set the month part of the value
                this.SecondarySelector.DataSource.SelectedItem = source.SelectedItem;
                if (source.SelectedItem != null && this.Value.HasValue)
                {
                    // Get the last day of the month
                    this.Value = new DateTime(
                        this.Value.Value.Year, ((DateTimeWrapper)source.SelectedItem).DateTime.Month, 1);
                }
            }
            else if (source is DayDataSource)
            {
                // We don't care about the day
                this.TertiarySelector.DataSource.SelectedItem = source.SelectedItem;
            }                       
        }

And there we have it DateTime Picker control which you can customised to show the selector that you want to show under different experiences. Our main job has been to refactored some of the code in the toolkit in order to access it from outside and also the changes to the xaml, nothing too taxing. I am pretty certain that this same approach could be used on the Time Picker, I have not tried this however there does not appear to be any particular reasons why this would not be possible.

As always interested in your thoughts and feedback…

What this space for more about the WP7Contrib soon to hit the shelves at a Codeplex near you….

You can download the code from here on Codeplex and take a look at spikes where you can find this sample and others or you can get it from here

WP7 Contrib – we made it!

All I can say is that Ollie and myself are super excited that after a number of months we have finally brought toghether all bits and shaped them into something that we are ready to release. We are very much at the start of this journey with a long road ahead so we would really like to hear your feedback, comments on new features coming and of course any contributions that you can make. The WP7C was intended for WP7 however there is no reason why you could not use some of the more general pieces in your SL App today.

WP7 Contrib (WP7C) has been something that started I thinking about after working with Simon Ransom on a WP7 App for the WP7 launch showcase. As with the majority of bleeding edge projects time was tight and although we both use SL in our day jobs there were a number of issues that we hit and as time went on and more people got there hands on devices then we started to see these same issues coming up as common problems that people were facing when developing on the device. Most of these issues are well documented now so I am not go into more details here but we will cover these off in a number of the up and coming posts.

Our vision for WP7C is to provide a useful set of tools so that we and now you can use in order to help build your applications quicker. You can head over to http://wp7contrib.codeplex.com/ and download the latest release. You can also read about  high level descriptions for each of the components that can be found in WP7C for completeness I have listed them below as well.

  • Caching – provides a set of caching services that will help with implementing caching
  • Collection – provides a set of collections that have additional bits added to them to help with common tasks
  • Common – provides helpers; base classes and serialisation bits
  • Communications – provides support for common networking problems
  • Messaging – provides a useful messenger extending MVVM Light’s messenging interface
  • Services
    • Location
    • Logging
    • Navigation
    • Resources
    • Settings
    • Storage
  • View – provides a number of great controls for building the UI.
    • Behaviors
    • Binding Listener
    • Converters
    • DateTimePicker
    • Extensions
    • Helpers
    • Orientation
    • Sliders
    • Themes

Stay tuned for more posts on how to use the WP7Contrib and always I look forwards to your comments.

Register for the Silverlight Firestarter!

SilverlightFireStarter

Light up your Silverlight skills with the all-new Global Silverlight Firestarter!

What is the Silverlight Firestarter?

–          An Event: A one day, global, live streamed and on demand event keynoted by Scott Guthrie

–          Training: New self-paced labs and walk through videos

–          Interactive: Got questions? Get your answers! Watch live and ask the Silverlight product team questions during the event.

–          Why Silverlight? Silverlight is Microsoft’s strategic development platform for building interactive applications across desktop, phone, and the browser.

Something for Everyone

–          Just starting out with Silverlight? Watch our On-Ramp sessions and work on hands on labs to get you started.

–          Already Building business applications? Watch the event live and learn how to create compelling business applications with Silverlight.

–          Got questions? Engage with the Silverlight product team live or in person with our interactive chat.

When
Register
How Much?

December 2, 2010 8am to 5pm PT
Register Online, Now!
Nothing! This is a free event

After the live event keep fuelling the fire!

Dive deeper with additional hands on labs and videos that build on the live session content, accelerating you ahead of the crowd.

–          Watch the entire event on demand!

–          Plus, new self-paced labs and walk through videos

–          On Ramp Labs (100 level)

  • Hands on labs specifically focused on helping new developers get up to speed quickly on Silverlight
  • Do you know WinForms? HTML? ASP.NET? Want to learn Silverlight? We have a lab for you!

–          Building Better Business Apps (200-300 level)

  • Hands on labs focused on taking advantage of Silverlight to build real world business applications
  • Apply Data Strategies, Patterns, Out of Browser, RIA Services, and much more using Silverlight

–          Turnabout is fair play! Watch a video of our experts doing the labs themselves.

F I R E S T A R T E R     L I V E     A G E N D A

8:00 am Silverlight Firestarter Keynote Scott Guthrie
9:00 am Masterful Data Strategies with Silverlight and WP7 Jesse Liberty
10:00 am 15 minute break
10:15 am Roll Out Your Business Apps Today with RIA Services Pete Brown
11:15 am MVVM: Why and How? Tips and Patterns using MVVM and Service Patterns John Papa
12:15 pm Lunch break
1:00 pm Silverlight Today and Tomorrow (Special Guest Panel) Panel
1:30 pm Building Real World Silverlight Apps Tim Heuer
2:30 pm 15 minute break
2:45 pm Tune Your Application: Profiling and Performance Tips Mike Cook & Jossef Goldberg
3:45 pm Killer Performance Tips for Silverlight Windows Phone 7 Jaime Rodriguez
5:00 pm After Party!

*** Sessions are subject to change

Spread the Word!

–          Blog and tweet to spread the word about the Firestarter!

–          Ask people to add the Twitter hash tag #slfs10 to their tweets

–          Use the banners and blog bling (attached)

Questions

Got questions? Ask slfs@microsoft.com

The cleansing process

I spend a large proportion of my time collaborating with UI designers and UI interaction designers where we work closely together to produce interactive UI’s for customers. As someone who is a novice when it comes to Adobe Illustrator and Photoshop I am very reliant on the import functionality in Blend. In this post I want to talk about a simple process that we have adopted to help with bringing those assets from AI and PS in our Xaml based projects.

Before the import features in Blend appeared we used the cool plug-in from Mike Swanson which would allow us to convert vector art work in Xaml. This was incredibility useful and mean that we reduce the time it took to convert these assets into Xaml and then modifying the Xaml in Kaxaml or in Blend. The process worked for us and we continued down this path until the import features in Blend improved and are now at a state where we can easily use the import functionality in Blend to convert these assets even easier.

But, that is not where the story ends, if you have tried out the import process on complex AI or PS visuals then you will have found that when Blend performs the import it positions each layer into a Canvas and will also import any images into the project as well. All in all this is cool however not so much when you have an existing project where you are happy with the code architecture and the folder structure of your application. And, this is what I want to dig into in this post is how to use the import functionality to your advantage.

Where do we start, ok so lets imagine that you have a project which you have setup or a developer on the team has created, its nicely structured and potentially uses MVVM or even a MVVM framework like MVVM Light. We also have a bunch of great looking designs that we need to convert into Xaml assets. We have a couple of options available at this point; we can import directly into the main solution or we can create a separate project a scratch project where we can import into. Admittedly at first I started out by importing directly into the main solution however this became a headache as the solution becomes polluted, by this I mean that when we do the import Blend will create a new folder in our project to hold the images that are referenced in the AI file however we are more than likely have an images folder in the project where all our images live. And for me this is where the management headache begins as we have to work out which images we want to keep and the ones we want to remove, and we also have to then move these images to the right folder and change the references to these images from the Xaml. All in all not too difficult when we break them down but on a large import this can become rather sticky very quickly.

Because of these issues what I have found is that importing into a scratch project is a smoother process for creating your Xaml assets and managing what images you want to keep. So the process goes something like this.

Create a scratch project and setup the folder structure for your Resource Dictionaries and images to mirror the same structure in the main project. Then import you AI or PS file into this project.

Next start to clean up your imported Xaml, the majority of the time you will want to ungroup the visual elements from their containing canvas as the visual elements will have been relatively positioned to mirror the layout defined in AI or PS. You will also find that the designer will have used a number of different layers to create the final appearance of an element. For example the designer may have used 4 different layers in order to create the colour of an element. In these cases my approach is to use the colour picker in Blend to find out what the colour is of the topmost layer, create this colour as a resource in your Resource Dictionary and then remove all the underlying layers until your left with the topmost then apply your newly created colour resource so that the visual element looks like the original. We could leave the visual elements as is however there are performance issues that we may encounter when doing this, in that if you have a list and you are planning on using this visual a number of times then those hidden layers are going to be present in the visual tree which means that the framework will render these and will have an impact on the performance of the application.

Other items to look out for are drop shadows on elements, when performing the import the drop shadows will be translated in a png images. In the majority of cases removing these images and replacing them with a drop shadow effect is the best mechanism, however there are some cases where the png works better. These situations are related to interaction design and occur when you are either; animating the visual elements on screen from one position to another; or you animating the drop shadow effect itself; in these circumstances then leaving the png is desirable and you may also consider using the EnableGPUAcceleration param at the plugin level along with setting the Bitmap Caching mode on your Xaml element.

By this stage you should now have cleansed your import and are ready to start styling and templating the imported visual elements into controls. There are two options available to you at this stage and they are related to your experience and confidence around the templating of the controls.

The first option is to group up the different visual layers that you want to make into the control, the majority of the time grouping them into a Grid or a  Canvas will work for you. From here you can then right click on the layout panel that you created and select “Make into Control” option where you can select from the popup dialog the control that you want to create a style for. From here you can start to assign the visual elements to the parts associated with that template.

The second option is to drag onto the art board the control that you want to style and template and size the control to be the same as the visual elements. Right click on the control and select the “Create a Copy” sub menu option located under “Edit Template” option. This will then provide you with a default template which you can then start to modify so that it takes on the appearance of the visual.

The first option works well if you have intermit knowledge of the template you are creating, it can also work well when you know that you are creating styles and templates for controls which are of a fixed height and width. However, if this is not the case then the second option is a preferred route.

The styles, templates, colour and brush resources that you are using need to be added into the correct Resource Dictionaries. By following this approach you can then pick up the visual elements and merge them into your main solution along with the modifications to the Resource Dictionaries and moving any images that you are using into your images folder.

I hope this insight helps both designers who are creating assets using Adobe products to think about some best practices on how you construct your designs and for the Blend folks this should help with cleaning up the imported Xaml.

As always please let me know your thoughts and also what you have found works best for you.