Semantic Zoom with MVVMLight – Windows 8 Metro

This week I’ve been trying out some Windows 8 Metro development and by doing so I came across something I think will help out other devs.
I wanted to try out one of the key new features that is presented in Windows 8, called Semantic Zoom ( read about/view it here ).

But because of the fact I’m mostly familiar with Windows Phone 7 development, I wanted to use Laurent Bugnion’s MVVMLight framework also on Windows 8. You can get a v4Beta1 version here…

So by doing so, I needed to tweak my code so it would fit nicely with the Semantic Zoom pattern. Let me show you how I did this.

First create a new MVVMLight Project

image

Than open the Model folder and add a class called Car.cs

 

And a class called Manufacturer.cs

These 2 classes will define your Group and Items needed for the Semantic Zoom. So for the Zoomed In view we will be presenting all Cars that we have ( grouped by manufacturer ) and in the Zoomed Out view we will show a birds eye overview of all Manufacturers with some general details about the amount of Cars available.

Next thing on our list is adding an ObservableCollection of Manufacturers to the MainViewModel.

Be sure to initiate your data, we will now for this demo do this in the MainViewModel constructor.

 

Now open up your MainPage.xaml and get rid of the following TextBlock

Put following code into place ( where the textblock was previously set ) to get your title and backbutton

So now we need to add our Semantic Zoom control, do this directly underneath the backbutton and page title xaml

 

Before we continue we will be adding a CollectionViewSource, this is needed to fill the Item grid later on in the Semantic Zoom control! You place this inside the MainPage.xaml <ResourceDictionary> tag, it should be there already and contain <ResourceDictionary.MergedDictionaries> tag… Take note that it is actually here that we will be binding to our ObservableCollection froml our MainViewModel!

 

So with this in place we can continue with our ZoomedIn view, all we will be doing is defining visual elements on how we want to structure our data. In our case we will be adding the Manifacturer name as Group header with Car models underneath it, to accomplish this add following xaml inside the <SemanticZoom.ZoomedInView></SemanticZoom.ZoomedInView> tags

 

Now that the ZoomInView is ready, add following xaml for our ZoomOutView. Now we will again show the Manufacturer name but only with a total Car count underneath it so we can get our birds eye overview! Place the code inside the <SemanticZoom.ZoomedOutView></SemanticZoom.ZoomedOutView> tags

 

Before we are done we do actually need to add one line of extra code in the MainPage.xaml.cs file! To get the ZoomedOutView working we need to link the groupGridView with the groupedItemsViewSource

So inside the constructor of the MainPage.xaml.cs add following line underneath the this.InitializeComponent(); call

And that’s it… if everything goes well you should have following result

image

image

The complete solution can be downloaded here… MvvmLight1

Tweetsharp and AgFx – Windows Phone 7

Being a big fan of AgFx for any online data retrieval, I was exited to see Bjorn Kuiper his blog post about using Tweetsharp together with AgFx in a WP7 app. You can read all about it here… it shows you how to display tweets from a specific users’ timeline.

But like many blog posts, most of the time you’ll have to tweak them to work in your own scenario. So also with this one, I needed to manipulate some code to get my case working. Best to start off, is downloading Bjorn’s example here.

What I wanted to achieve, was to show a list of tweets done by a Search, also through the use of Tweetsharp and AgFx of course. But what I soon found out was that the code of Bjorn uses the class TwitterStatus that contains a tweet, in my case the returning items are of type TwitterSearchStatus. They are actually not that different, but I ran into some serialization/deserializations issues.

So what was my problem… when you get your search results back from Tweetsharp you want to serialize them so that you can use the AgFx feature. In Bjorn’s example, he strips the Entities from the TwitterStatus before serializing. Found in the Execute method of the TwitterLoadRequest class.

 

But like I stated before I’m not working with TwitterStatus but with TwitterSearchStatus and it seems that performing the same action has no effect and I was still getting problems with the Entities property when Deserializing.

So how did I solve this, well I used Json.net from James Newton-King, also available as a NuGet here. So, instead of using the .Net DataContractJsonSerializer like Bjorn, we use the JsonConvert.SerializeObject. This gives us following code that replaces the one show above:

What you will notice is that I’m doing a special kind of Serialization… using a DynamicContractResolver! This is needed to manipulate the Json serialization, because if we don’t do anything, we’ll still have an output Json string containing the Entities properties.

So to fix this, you’ll need to interact when Json.Net tries to convert your class to Json, how to do this is is by creating your own class that inherits from DefaultContractResolver.

 

As you can see, Json.net finds properties to serialize, so he will pass the CreateProperties method, what we do here is use Linq to filter out the Entities, resulting in a total Json outpot string containing serialized TwitterSearchStatus objects without any Entities property.

The only thing left to do is Deserialize everything back in the Deserialize method of your AgFx DataLoader class.

 

So now you’ll be getting TwitterSearchStatus objects back from AgFx that you can use in your WP7 Views! Happy coding…

Resize images to be used on Live Tile – Windows Phone 7

Recently I added a live tile feature to one of my WP7 applications.
The app tile would show an image of a person, retrieved from a RSS feed.

Now because of the fact that the image is of a person, it’s not squared, but portrait. Meaning that the width of the image is shorter then the height. Also the image I need to display is larger than the windows live tile.
So when you just try to display this image without any modifications, you’ll get a weird result.

The original image

To fix this, you’ll need to resize the image.

First of all, download the image and map it to a BitmapImage object, you can just use an URI that points to the image on the web for this.

One note, before you can start manipulating the image, you’ll need to be sure it has been downloaded completely, so register to the ImageOpened event.

If needed you can also add code when there has ben a failure with downloading the image.

So when you are sure the image has been downloaded you can start manipulating it. Now an extra note here, there is a great library available on Codeplex ( and NuGet ) that adds many extension methods to the WriteableBitmap that are handy when dealing with any image manipulation. It’s called WriteableBitmapEx and can be found here ( http://writeablebitmapex.codeplex.com/ ).

We need to target our image to a tile of 173 by 173 pixels, thus we need to find the aspect – ratio. To do this, we first need to determine what is the largest side of our image.

After this we can determin the destination width and height…

All we need to do now is performing the actual resize.

Now that you have ‘constructed’ your resized image, you’ll have to store it on the phone’s isolated storage before you can use it as a live tile image!

The live tile needs an URI to this saved image to work correctly. To get this done in one go you can use following method SaveTileBitmap, it will save the image and return you the correct URI.

So the last stop is using this method to get the URI and constructing a live tile…

You’ll need to give the image a name, but any name will do.

BUT when you do this, you’ll notice the image is still scaled to 173 px! This is something I didn’t except, but it seems the tile will always try to stretch to 173 by 173, thus miss forming our image.

Resized image – wrong!

To compensate we need to paste our resized image on a dummy 173 by 173 before storing it in the isolated store… In other words best to store a correct sized square image with the resized image pasted inside it at the correct location.

Because we know the width was the smallest, we need to center the image on the tile! So we will be merging the resized image starting not at position 0.0 but compensating for the smaller width!

Resized image – correct!

LongListSelector – Windows Phone 7 development

If you are using a Windows Phone 7, you’ll have noticed that when you want to go through your People list they are all ‘grouped’ by one character. And when you press one of those characters, you’ll get a nice overview of all available groups, again shown by a character.
Example example

Now if you are a wp7 developer and want to have the same kind of behaviour for any kind of ‘lists’ you want to present to the enduser, you have 2 options, 1. develop your own control or 2. use the LongListSelector available in the Sliverlight toolkit for WindowsPhone7!

Now to use this control, you better read up 2 posts available on windowsphonegeek

Now if you follow these posts, you’ll notice you won’t get the same look and feel as on the People list in the Windows Phone itself… now to overcome this, you’ll better read up Benjii’s post on how to use the LongListSelector!
Because when you follow his instructions, you’ll get a better UI in reference to the People list on the Windows Phone.
But somehow when I used his solution, I was not able to get a correct Item Selection Change event to Command working. Somehow Benjii’s group class won’t let me cast back to one selected item in the ViewModel.

So again I needed a solution! And after some twitter chatter and a question on stackoverflow, I was directed to a custom implementation done by Claus Jørgensen!
The best way to look at his grouping class and LongListSelector usage, is to download his weather app from GitHub!
It contains a fine example on how to use the LongListSelector and also an extension that is needed to get Command binding to the SelectionChanged event!
His Grouping class also makes it possible to get the correct item from when the selection changed event get’s fired!

I did however change one small detail of his Grouping class ( LongListCollection.cs ), because when you do nothing with Claus’ class, you’ll only see the item group keys of the available items. And Benjii’s solution, first add’s dummy key/list items so that you’ll get the same overview as on the People list, when a group has no items the group key will be greyed out!!

To get this working with Claus’ class, I added a DefaultHeaders list! Here is my implementation of the class: