Tech Blog

Jay's Technical blog

Mango Live Tile Helper

21 October 2011
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

I’m in the process of unveiling a new app on the marketplace (it’s actually ready to publish right now, but I’m waiting to publish a blog post on it later). During the process of creating this app (really it’s a framework), I needed/wanted to enable a Live Tile. While the whole Live Tile thing is not all that complex, I decided to make it even simpler with a single class.

I had been told Live Tiles can be created in 6 lines of code; with my helper I have reduced that number by 66% (so 2 lines of code). I also used this code to produce a new version of my comic reader that let’s you pin a single comic to the desktop (and of course it shows a portion of the cover/first page in the Live Tile).

The Code

I created a class that is called LiveTileTempate. It’s all you need in your projects. All you need to do is create a LiveTileTemplate Instance with the proper values set and then call the UpdateApplicationTile, or CreateSecondaryTile methods. So here’s some example code for updating the application’s pinned/Live Tile:

     LiveTileTemplate tileCreate = new LiveTileTemplate
     {
          FrontSideTileTitle = "Live Tile Demo",
          FrontSideTileCountContent = (new Random()).Next(100),
          BackSideTileTitle = "Back Side",
          BackSideTileContent = "My Content on back of tile"
     };
     tileCreate.UpdateApplicationTile();


So let me explain all this, we create a LiveTileTemplate and then simply call the instance’s UpdateApplicationTile method. Most of this is pretty self-explanatory. We set both the front and back titles that appear under the tile, we set a number which appears on the front, and we set the back to have a message on the tile (we go through all the properties further down this post).

This same code could be used to produce a Secondary tile with 2 changes:

  1. We have to set the NavigationUri property of the LiveTileTemplate instance
  2. The last line would need to call CreateSecondaryTile instead of UpdateApplicationTitle

Let’s see an example of a Secondary Tile:

     LiveTileTemplate tileCreate = new LiveTileTemplate
     {
          FrontSideTileTitle = "2nd Live Tile",
          FrontSideTileCountContent = (new Random()).Next(100),
          FrontSideBackgroundImage = "/Koala.jpg", // this would never fly in the Marketplace process (icon needs to reflect app)
          BackSideTileTitle = "2nd Back Side",
          BackSideTileContent = "This is the backside of the second tile",
          NavigationUri = "/Page2.xaml?value1=content+in+uri&randomNumber=" + randomNumber.ToString()
     };
     tileCreate.CreateSecondaryTile();

So this example has a few more elements in it. We are now setting the NavigationUri to a relative path to a xaml page in our app and can include a querystring. We also set the Front’s image using content inside the XAP. This can also be a URI pointing to an image on the Internet (and can even come from IsolatedStorage, but more on that in a later blog post).

Finally we call CreateSecondaryLiveTile(). The naming of that method is not 100% accurate. It actually will detect changes and apply an update to your tile instead. The big thing is that when updating a secondary tile you have to provide all the information (not just changes), because we aren’t given the ability to reload the content that was previously entered, so we don’t really know, for instance, what was originally the Content of the back of the tile. We can only really detect that there was a tile there before pointing at a specific URI in our XAP.

Additional Functions/Methods

Speaking of existing tiles there are a couple additional static methods that are exposed. You can call LiveTileTemplate.GetExists(“/path/to/aPage.xaml?querystring=somevalue&qs2=someValue&etc”) and it will return to you whether a SecondaryTile already exists for that Uri. This is useful because when you create a secondary tile the OS automatically takes the user to the start screen. If the Tile already exists then they stay in the app. You want to be able to let the user know that the tile was updated instead of created in this second instance and now you can know what is going to happen next before proceeding with the action. My comic reader throws up mock toast notifications in the case where the tile has been updated instead of created.

Finally there is one more static method that you might be interested in. LiveTileTemplate.DeleteSecondaryTile(“/path/to/aPage.xaml?querystring=somevalue&qs2=someValue&etc”) deletes a previously created tile using the Navigation Uri.

There are also one more additional method and a constant that are pertinent to using an image from IsolatedStorage, but that will wait for another post.

LiveTileTemplate Properties

Here’s the properties (and their meaning and additional info) that you can set in the LiveTileTemplate Class:

  • FrontSideTileTitle – The title that appears on the front side of a tile (If this value is null then class will try to infer the name of your app from the Assembly’s name)
  • FrontSideBackgroundImage – Set’s the image for the front side of the tile (the default is to use the Background.png file that is part of your XAP. Also, I’m not sure if you are allowed to radically change this and get accepted into the marketplace, so change this with caution would be my advice)
  • FrontSideUriType – sets whether FrontSideUri is a relative or an absolute Uri. (We default to relative, but if we detect an isolated storage Uri we switch to an absolute Uri).
  • FrontSideTileCountContent – (optionally) sets the number that will appear on the front side of the tile. (We default to null which means no number)
  • BackSideTileTitle - The title that appears on the back side of a tile (If this value is null then we grab the title of the front side of the tile or if that is null we use the name of the Assembly)
  • BackSideTileContent – This is the text that will appear on the back side of your tile.
  • BackSideBackgroundImage – Set’s the image for the back side of the tile (leaving this blank will use the user’s accent color)
  • BackSideUriType – sets whether BackSideUri is a relative or an absolute Uri. (We default to relative, but if we detect an isolated storage Uri we switch to an absolute Uri).
  • NavigationUri – sets the Navigation Uri that is used when the user clicks the live tile. (this should be a deep link into your app and may even be a link that in a place in your app that is inaccessible in other ways; it’s pretty cool that you can do this)

Download

You can get the class and a sample project from my source code repo for this. I have a couple more things I will be doing with this (and another article.. hopefully soon).



Download Queue code…

01 October 2011
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

Here’s code/slides to my recent talks (I thought I already posted this)


Repo for the Source code


Intradynamics, LLC: Open For Business (again)!!

01 October 2011
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

I just wanted to throw out a quick post letting the world know that I went independent again. Today is the first day in my business’ new start! I’m totally psyched! I’m going to be doing a variety of things: Silverlight (of course), Mobile, ASP.NET, and Javascript (aka HTML5 aka Ajax/Web2.0 aka DHTML… etc.). (and this is just my plan for the first week <grin/>).

One word of warning, I will be interspersing some content in here that isn’t purely Silverlight (and yes, this blog is about to be back in full motion again.. well, I hope so). I will try to keep the content pertinent to Silverlight though (but some of this stuff might be just off the corner.. for instance I have an upcoming Orchard CMS post coming very soon).


The Perf Tweak to my WP7 App that turned it from &ldquo;ho hum&rdquo; to &ldquo;Wow!&rdquo; (it works in Silverlight3+ OOB too)

01 October 2011
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

[If you are in a hurry then the answer is CacheMode=BitmapCache. If you want to read the story/know more then read on]

I have been working on a Windows Phone 7 comic book reader over the last couple months. It’s actually done and has seen a few revisions. During the testing of my original release, my friend (and fellow member of the Florida WP7 developer’s club) Brian Kassay suggested that I should use a different library for my image gestures.

You see when you are viewing a comic book page with my reader you are actually looking at a single image which you can move around on the screen as well as can zoom into/out of, and change pages. The page/image viewer was really sluggish on the device. Brian thought it was the gesture library I was using, but nope. after wiring up a different library (the same one Brian uses), the performance was absolutely identical. No change whatsoever.

After listening to a bunch of performance podcasts and finally got my head wrapped around the problem. I turned on redraw regions (which is another tip I can give you), and saw that my image was re-rendering everytime I touched it with my finger (panned it around the screen)

Back in the Silverlight3 timeframe Microsoft added the ability to create an out of browser app that takes advantage of GPU Acceleration.. One of the things that surrounded this feature was a little property that I had totally ignored: CacheMode. I kind of thought the whole GPU acceleration thing was more about building games and ignored the topic. BUT, GPU Acceleration is on by default in WP7 (and I don’t think there is a way to turn it off). It’s on because guys at Microsoft knew we would need to take advantage of the GPU in WP7 apps more often then in standard Silverlight apps (because we are dealing with a CPU-limited phones). So, I switched this property from the default to “BitmapCache” on my image which was rendering constantly. Instantly I went from slow to fast when panning/zooming the image.

You may be wondering “should I turn this on for everything thjen?" Just cache the entire LayoutRoot?” Well, MSDN suggests to “Set the CacheMode property when you need to increase performance for content that is time consuming to render.” CacheMode=BitmapCache simply causes the element it is applied to to render a single time. The resulting Bitmap is cached and re-used for later render cycles (this is probably taking up some memory somewhere). This is great to use on elements that to don’t animate. I would suggest that you look at your WP7 UI and turn on redraw regions. Watch your app you will see what is rendering excessively. Try setting the CacheMode on these elements and see if your performance increases.


Silverlight/WP7 tip: Detecting when in VS Design Mode

01 October 2011
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

I have struggled with dealing with this for sometime, and ultimately gave up. Today, I happened across something interesting. I’m doing some intense Isolated Storage stuff with WP7, and I’m using ViewModel. I analyzed one of the errors I was getting in the VS XAML designer, and discovered what in my ViewModel VS didn’t like. So here’s what I discovered.

The Technique

You can detect Visual Studio Design Mode by checking isolated storage. It throws an error when you try to access it from within Visual Studio. This is immensely useful when working with ViewModels that you are instantiating in either XAML or CodeBehind or even some kind of locator class. I wrote a little class in the vein of some of the code in MVVM Light (hopefully I can get Laurent to add this to the next version).

using System;
using System.IO.IsolatedStorage;
namespace AmazingPocketComicsViewer.Model
{
publicclass VSDesignDetector
    {
staticbool? isInDesignModeStatic = null;
publicstaticbool IsInDesignModeStatic // Convenient method that can be accessed out of an inherited class
        {
            get
            {
if (isInDesignModeStatic.HasValue)
                {
// only do the check once and use the last value forever
return isInDesignModeStatic.Value;
                }
try
                {
                    var isoStor = IsolatedStorageSettings.ApplicationSettings.Contains("asasdasd");
                    isInDesignModeStatic = false;
return isInDesignModeStatic.Value;
                }
catch (Exception ex)
                {
// Toss out any errors we get
                }
// If we get here that means we got an error
                isInDesignModeStatic = true;
return isInDesignModeStatic.Value;
            }
        }
protectedbool IsInDesignMode
        {
            get
            {
return IsInDesignModeStatic;
            }
        }
    }
}

And that is it! Enjoy!