Microsoft just announced what happens to your non-Mango app (WP7.0) if you publish a Mango app (WP7.1) to the marketplace. Basically if you upgrade your app to 7.1, you will no longer be able to maintain the 7.0 app for people who still haven’t upgraded yet (and we know from the last update that that can take a while).
However, it is possible to make a 7.0 app that uses Mango features if the user has upgraded to Mango. That way you can continue to build a 7.0 app, and the moment the user upgrades to Mango, he will get additional features available. All this using a little “reflection magic”. The certification requirements does kind of hint at that this is not allowed, but some apps has already made it through certification, so this seems to be considered OK to do, and it also works great as well.
So how is this done? We can use the method of the Type object to get identifiers of methods, events, constructors, properties etc. by using their names. This way we will never write a piece of code that explicitly uses one of these (which the compiler would reject), but instead at runtime will attempt to locate them, and if successful execute/access it
But before we attempt doing that, we can perform a check for whether this is a mango device (or newer). Mango is v7.1, so it must be version 7.1 or newer:
bool IsMangoDevice = (Environment.OSVersion.Version >= new Version(7, 1));
We can also get access to types we don’t have yet in the 7.0 compiler but the 7.1 device has. For example, the StandardTileData class used to create secondary tiles for your app can be accessed using its full name and assembly:
Type t = Type.GetType("Microsoft.Phone.Shell.StandardTileData, Microsoft.Phone");
If we continue down this path, we can actually create a secondary tile on a mango device, and still have the app be 7.0. That means you can TODAY submit an app to the marketplace that uses mango features, and people with developer devices will get mango features now! (again note that this might cause problems during marketplace certification, but some apps has already made it through and is available today!)
Anyway… here’s the code that creates a secondary tile:
//get the constructor for the StandardTileData and create a new instance of it
var newTileData = t.GetConstructor(new Type[] { }).Invoke(null);
//Get the setter method for the title property
var setMethod = newTileData.GetType().GetProperty("Title").GetSetMethod();
//Set the tile title
setMethod.Invoke(newTileData, new object[] { "This is my new tile" });
//Get the create method for the shell tiles
Type shellTileType = Type.GetType("Microsoft.Phone.Shell.ShellTile, Microsoft.Phone");
var createMethod = shellTileType.GetMethod("Create");
//Create the tile, with the uri and tile data
Uri uri = new new Uri("/MainPage.xaml?Test=This_Came_From_A_Secondary_Tile", UriKind.Relative)
createMethod.Invoke(null, new object[] { uri, newTileData});
Or how about setting the system tray color?
typeof(Microsoft.Phone.Shell.SystemTray).GetProperty("BackgroundColor").
GetSetMethod().Invoke(null, new object[] { Colors.Red });
Of course you should only call these methods if the device is a mango device, so use the check shown first before executing this code. I created an extension class that neatly encapsulates this and only executes the code if it’s supported. Examples:
//Set tray color if supported
MangoExtensions.SetTrayColor(Colors.Blue);
//Add hold event handler to a control (onHold is of type RoutedEventHandler delegate):
myControl.AddEventHandler_Hold(onHold);
//Show "Create secondary tile" button if supported:
createTileButton.Visibility = MangoExtensions.IsMangoDevice ? Visibility.Visible : Visibility.Collapsed;
//Create/replace tile:
MangoExtensions.CreateTile("My Tile", new Uri("/MainPage.xaml?parameter1=value1", UriKind.Relative));
You can download the entire extension class here: Download