MVVM binding a ListView to an Enum with translation

Sometimes we need to visualize a list of enum values to the user, so he can make a
selection and if possible we would like to make this reusable for any enum used in our app.

But there are some problems when we would try to get this done… Enums are great for storing some kind of selection, but they are not easy to use in an MVVM list binding scenario! Certainly not if they need to be presented in a readable manner nor while different languages are supported.

But there is a way to get this done! Let me show you a solution while using a Windows Phone 8.1 store app, but the code will also work in Windows 8 store app and most of it will also run in a Windows Phone Silverlight app.

The enum we will be using…

The setup of this example is simple, we have a page with a ListView that’s bound to an enum in our ViewModel.

You’ll notice that the ItemSource is not binding to some collection! It’s the actual type of the enum and through the user of a converter we will return the needed display values. We are also showing the selected value inside a textblock, to show you that we are really getting an enum value!

In our ViewModel we have following properties.

The actual enum will be returned through the SelectionType property and the return type is System.Type. Also when the ListView has a selected index change, you’ll see that we’re using that current selected index to determine what enum value was actually chosen and we set that to the SelectedValue property.

So how do you initialize this, just by getting the type of your enum! In this example we init it in our constructor.

Now a ListView can’t do anything with an enum type, so we need to convert this in our EnumTypeToListConverter. The actual convert part looks like this.

We get the enum type as value parameter and use this to get all values of the given type through use of the general Enum.GetValues method. With this we have all values that the given enum has, but these aren’t yet usable to present inside the app! To fix this, we use a resource loader to get a nice display value for each enum value from the current loaded language resource! Finally we convert this to a list and return it to the ListView.

For this all to work you’ll need to add some resource files for each language you are going to support and inside each resource file you’ll need to add a display value for each enum value.

In our case we are using following format [enum type name]_[enum value]. So for our gender enum this gives following resource entries. For adding these resources, take a look at this good explanation here…

image

With all this in place you’ll get following result

 

As always a complete working version can be found on my github here…

Windows Phone Image button style

So you are creating your latest windows phone app and would like to add some fancy designed icons or images… But instead of just showing these, they’ll need to react as a button! By the way, we normally use vector data, but that is not always to our disposal. It could be we have a nicely designed icon in several resolutions.

Well that’s easy you think, we’ll just add a button and put that image inside it – here is the code

But when you just use it like this, the image won’t look good! It will have the default button border around it and that’s not something you want.

image

Than you think a little bit about it, maybe search the internet and yes, behold Jeff Wilcox used something back in the wp7 days that could be usefull! An EmptyButtonStyle, it’s a button style stripped to the bare minimum! So you add that and use it – here is the code

But again you’ll notice it’s not perfect… ok it has no visual references anymore to a button, but pressing the image will now also no longer give a visual indication!

image

On wp8, pressing a button, the content will slightly grey out to tell the user he’s pressing that button! So we need to check the state of the button to play with the opacity and enable this visual effect again! Behold the ImageButtonStyle

So when running the app you’ll notice no difference with the empty button style, until you press it! It will now grey out the content a little bit.

As always a test project can be found on github here: ImageButton project

Xbox music integration – windows phone

So you’ve created a Windows Phone app that has something to do with music? Well chances are you can gain some money with it thanks to the Xbox music affiliate program!
All you need to know to get this up and running is available on MSDN here… but let me show you my implementation, because I find the docs on MSDN a bit chaotic.

So first things first, open up a publishers account on Rakuten Linkshare through this url http://www.linkshare.com/join/ This is needed, because they are the ones gathering the click information and doing the payments.

* Pro tip * Note that at one point you’ll need to fill in website info – here you’ll have to put the URL pointing to your app in the windows phone app store! This is important, because that way Xbox music can verify your request ( more on this later on ).

* Pro tip * Be sure to take into account that you’ll need to fill in form W-8BEN if you live outside of the United States, for being in order of payment taxes!

After you filled in all the needed info and your account is in order, open the LinkShare website and navigate to PROGRAMS > Categories – select category Entertainment > Music and look for Xbox Music and press the Apply button on the right side.

LinkShare

When you apply for a new advertiser, you’ll get an email notification stating that it will take 1 till 2 weeks before your application is approved! And here comes the important pro tip from above, this validation is done based on the app url you submitted earlier. So you’ll first need to add a working app to the store.

After a positive review, your app will be approved for generating links to LinkShare. So the coding/integration can begin!
In my app ConcertWall I wanted to show albums from a specific artist and when the user presses the image from that album, it will show Xbox music so you could play/purchase that album.

To get started with using the REST API service of Xbox Music, you’ll need to get a Client ID and Client Secret for your app. This can be obtained via https://datamarket.azure.com/ – you’ll need to register and add the app. All the details and steps are outlined on MSDN here…
With this info you then can set up your first method to interact with the service!

When you want to gather data, you’ll first need to request an access token from the OAuth service before you can perform any REST calls to the Xbox Music service. I’ve packed this call in an async method called RequestAccessToken.

It needs your client id and secret ( the ones you created on the DataMarket.Azure site ), a given scope – this is a fixed string http://music.xboxlive.com all this has to be passed to the token service – this is https://datamarket.accesscontrol.windows.net/v2/OAuth2-13 – as a http POST. You’ll get a response back that contains the needed access token.

This token allows you to do any HTTP Get REST requests to the Xbox Music service for a specific period. In my case I just wanted to show all albums of a given artist. I wrapped this in a method called GetArtistAlbums

The Service Request string is composed of different parts, let me show you each one

  • First the base url: _artistSearch = https://music.xboxlive.com/1/content/music/search?q={0}
    • So we are going to perform a search with a given keyword
  • The keyword: artistName = the input parameter of this method
  • We want albums so add: &filters=Albums
    • You can search for other items, be sure to check out the MSDN documentation
  • Add the access token: _xboxMusicRESTRequest = “&accessToken=Bearer+”
  • Concat with the actual urlencoded token: new Uri(serviceRequest + HttpUtility.UrlEncode(accessToken))

With that in place, you just fire a client.GetAsync() and the response return value will be a JSON string containing all found Albums mathing your search string. I found that this can be a big set with to much hits, so I filter out all albums that don’t have the given artist name in the artists list of each album!

* Pro tip * Do note we aren’t yet earning any money! For this we need to add Deep Links to Xbox music on our phone.

I now present these albums in a list so the user can press the image, with this I’m activating the Deep Link url to Xbox Music on the phone.

Albums

The correct deep link uri for each album is actually already inside the response result we got from our search query, but to gain money through LinkShare we need to modify it!
We need to reroute our request through LinkShare with the correct id’s so that LinkShare can track the requests and if needed award us points!

The correct link format is show below, only thing missing is your affiliate key for Xbox music – this id can be found by generating a link on the LinkShare site for Xbox music after your request for this advertiser has been approved! Just press the Get Link button and look for the http://ad.linksynergy.com/fs-bin/show?id= part it shows you the id!

But how do you use this deep link? Well put a WebBrowser control on your windows phone page and set it Collapsed.

Only thing left is triggering the navigation on this control with the given deep link url!

* Pro tip * Instead of doing this yourself, you can use this XBox music API wrapper ( pcl ) ! It contains all needed REST calls and also provides the possibility to add your affiliate id!

Happy money gaining!

Navigating to same viewmodel but with different data and keep navigation stack correct with MVVM Light

Long title, I know… and even with that the scenario I’m trying to describe isn’t clear yet, so let me explain even more.

In my latest app ConcertWall you can open a Venue and look at the concerts that are available, when you open up a Concert you can – again – go through to the same Venue and pick another Concert to get the details.

Now translated to the technical MVVM background this means: Venue viewmodel A > Concert viewmodel A > Venue viewmodel A > Concert viewmodel B > etc…

But when you try to do this in a normal MVVM Light way, you’ll break the Navigation stack! Because when you’ll navigate back from concert viewmodel B to the venue viewmodel A to the concert viewmodel A, you’ll notice A will no longer be visible but you’ll get B again!

This problem is easy to explain, you only retain one instance of the concert viewmodel and if you do nothing when navigating, only the last loaded datacontext will be shown each time you get on the concert view!

Now how can we fix this, there are several ways ( like Nico Vermeir shows one here ), but I like to use the SimpleIoc functionality that is present in MVVM Light and let it handle my instances instead of adding extra in memory containers!

So how do you get this working, first you’ll need to add a special method inside your ViewModelLocator called GetViewModel<T>

This is actually the real solution, all it does is keep track of all separate instances of a given viewmodel based on a key you provide! So no hassle with keeping track of it myself.

Only thing left to do is using this method when navigating to the viewmodel you want to track based on a key ( in our example the Concert viewmodel ).

Best thing to use as key, is the unique identifier that is present in your data model that needs to be shown on that view ( in our example the Concert ID ) and add that to the navigation URI.

Now when you navigate to the view, you can no longer use the MVVM Light datacontext binding in XAML! This because we’ll need to set it our self through use of the above provided GetViewModel method based on the key that is used in the navigation URI. So in the code behind of the given view, override the OnNavigatedTo method and inject the correct viewmodel datacontext!

I’m also calling a RefreshLayout method to refresh the current data on each view load, but depending on the app scenario this is maybe not needed.

With all that in place, you can go forward and call the same viewmodel with different data over and over, and keep your navigation back stack intact because of the added key inside the navigation URI.

Happy coding!