Pages

Sunday 29 April 2012

Live Tiles

One of the most expected features of Mango release were live tiles allowing developers to present data on the Home screen. I was quite exited about this feature especially that I wanted to give users opportunity to learn new words or whole sentences. You can see it in action on Multi-Translator Webpage or you can install it from Marketplace.There are actually few ways to present data in live tiles.

FindAndDeleteTile method
   1:          private void FindAndDeleteTile(string tileName)
   2:          {
   3:              ShellTile tile = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("DefaultTitle="+tileName));
   4:              if (tile != null)
   5:                  tile.Delete();
   6:          }

TileHelper class
   1:   public static class TileHelper
   2:      {
   3:          public static void CreateTile(string content, string fileName, string originalFileName)
   4:          {
   5:              TextBlock text = new TextBlock()
   6:              {
   7:                  Width = 173,
   8:                  Height = 173,
   9:                  TextWrapping = TextWrapping.Wrap,
  10:                  Foreground = new SolidColorBrush(Colors.White),
  11:                  Padding = new Thickness(5, 5, 5, 60),
  12:                  FontSize = 18,
  13:                  Clip = new RectangleGeometry { Rect = new Rect(0, 0, 173, 135) }
  14:              };
  15:              text.Text = content;
  16:              Canvas canvas = new Canvas() { Width = 173, Height = 173, Background = new SolidColorBrush(Colors.Blue) };
  17:              canvas.Children.Add(text);
  18:   
  19:              StreamResourceInfo sri = Application.GetResourceStream(new Uri(originalFileName, UriKind.Relative));
  20:              BitmapImage src = new BitmapImage();
  21:              src.SetSource(sri.Stream);
  22:              WriteableBitmap background = new WriteableBitmap(src);
  23:              WriteableBitmap bmp = new WriteableBitmap((int)canvas.Width, (int)canvas.Height);
  24:              bmp.Render(canvas, null);
  25:              bmp.Invalidate();
  26:   
  27:              for (int x = 0; x < canvas.Width; x++)
  28:                  for (int y = 0; y < canvas.Height; y++)
  29:                      //Detect the colour different from your canvas background (in this case Blue) 
  30:                      //and replace the background.jpg pixel with the one from your canvas    
  31:                      if (bmp.Pixels[y * (int)canvas.Width + x] != BitConverter.ToInt32(new byte[] { 255, 0, 0, 255 }, 0))
  32:                          background.Pixels[y * (int)canvas.Width + x] = bmp.Pixels[y * (int)canvas.Width + x];
  33:   
  34:              var iss = IsolatedStorageFile.GetUserStoreForApplication();
  35:              using (var stm = iss.CreateFile(fileName))
  36:                  background.SaveJpeg(stm, 173, 173, 0, 100);
  37:          }
  38:   
  39:          public static void CreateRenderedTile(FrameworkElement frameworkElement, string fileName)
  40:          {
  41:              WriteableBitmap bmp = new WriteableBitmap((int)frameworkElement.Width, (int)frameworkElement.Height);
  42:              bmp.Render(frameworkElement, null);
  43:              bmp.Invalidate();
  44:   
  45:              var iss = IsolatedStorageFile.GetUserStoreForApplication();
  46:              using (var stm = iss.CreateFile(fileName))
  47:                  bmp.SaveJpeg(stm, 173, 173, 0, 100);
  48:          }
  49:      }
  1. Default approach - using API
       1:          var filename = "/Shared/ShellContent/renderedF.jpg";
       2:          var filenameBack = "/Shared/ShellContent/renderedB.jpg";
       3:          TileHelper.CreateRenderedTile(frontBorder, filename);
       4:          TileHelper.CreateRenderedTile(backBorder, filenameBack);
       5:   
       6:          FindAndDeleteTile("Rendered");
       7:          StandardTileData NewTileData = new StandardTileData
       8:          {
       9:              BackgroundImage = new Uri("isostore:" + filename, UriKind.Absolute),
      10:              Title = "rendered - front",
      11:              BackTitle = "rendered - back",
      12:              BackBackgroundImage = new Uri("isostore:" + filenameBack, UriKind.Absolute)
      13:          };
      14:          ShellTile.Create(new Uri("/MainPage.xaml?DefaultTitle=Rendered", UriKind.Relative), NewTileData);
  2. Custom approaches:
    • Rendered - Saving the content of controls visible on the screen into a file and using it as a tile background
         1:          var filename = "/Shared/ShellContent/renderedF.jpg";
         2:          var filenameBack = "/Shared/ShellContent/renderedB.jpg";
         3:          TileHelper.CreateRenderedTile(frontBorder, filename);
         4:          TileHelper.CreateRenderedTile(backBorder, filenameBack);
         5:   
         6:          FindAndDeleteTile("Rendered");
         7:          StandardTileData NewTileData = new StandardTileData
         8:          {
         9:              BackgroundImage = new Uri("isostore:" + filename, UriKind.Absolute),
        10:              Title = "rendered - front",
        11:              BackTitle = "rendered - back",
        12:              BackBackgroundImage = new Uri("isostore:" + filenameBack, UriKind.Absolute)
        13:          };
        14:          ShellTile.Create(new Uri("/MainPage.xaml?DefaultTitle=Rendered", UriKind.Relative), NewTileData);
    • In memory - Saving a content of controls generated in memory into a file and using it as a tile background
         1:          var filename = "/Shared/ShellContent/inMemoryF.jpg";
         2:          var filenameBack = "/Shared/ShellContent/inMemoryB.jpg";
         3:          TileHelper.CreateTile(front.Text, filename, "Images/background.jpg");
         4:          TileHelper.CreateTile(back.Text, filenameBack, "Images/backgroundBack.jpg");
         5:   
         6:          FindAndDeleteTile("InMemory");
         7:          StandardTileData NewTileData = new StandardTileData
         8:          {
         9:              BackgroundImage = new Uri("isostore:" + filename, UriKind.Absolute),
        10:              Title = "in memory - front",
        11:              BackTitle = "in memory - back",
        12:              BackBackgroundImage = new Uri("isostore:" + filenameBack, UriKind.Absolute)
        13:          };
        14:          ShellTile.Create(new Uri("/MainPage.xaml?DefaultTitle=InMemory", UriKind.Relative), NewTileData);
Useful links: