FlipTile, CycleTile and various iterations of #wpdev sdks

As you might have realised, the last few weeks, cineworld app has been my obsession. I started work on WP8 port and then back-ported some changes to WP7 version of the app (its the only one that’s live at the moment so makes sense). So what did I do so far on it (WP7 version) ?

1) Moved to using 50% space when displaying film posters, moved film little on top of the posters, removed the button style that caused me many xaml exceptions on WP8
2) Moved to using good quality images only for ImageTile control.
3) Added background task to download data files and to set Tile images

This is live as we speak and a few people emailed me saying it looks great. Now I am not going to create yet another background task for WP8 version (since I wanted to use Cycle Tile Template for WP8 version of the app.
Microsoft’s own tile related pages show how to support newer tiles for WP7.8 and WP8 even though the app itself is built on WP 7.1 (Mango) sdk

So far I stayed away from temptation of managing image repository on the device. you can see that it gets messy eventually and you have to clean up and what not.. however after implementing basic solution, it started throwing exceptions.. files used for tiles cannot be remote. Bugger.. more work

Step 1): Download image files locally. I have been using AsyncWebClient (Custom wrapper with TaskCompletionSource) exposing awaitable DownloadFile method. Plug that in and download all the files. Its background tasks, I am not really fussed about parallel execution.. just manageable execution (read sync like)

Step 2): For Uri array using relative path and ??? still nothing. More work, a quick search about the net found me a couple of posts for “live tile isolated storage image WP7″ File Path in Isolated File Storage is the one that I first opened and a quick scan reminded me of “isostore” based Uri

Step 3): Save all the images to Shell\SharedContent and switch all Uri to use isotore:/Shell/SharedContent/Filename.jpg

The code below will help you create live tiles with new tile templates from WP7.1 (Mango) sdk based project. I will be using the same code for WP8 in coming days since its the same background task

A word to the wise:
* You cannot determine if the template used by Tile is Standard or a new one.
* What I now do is Create a CycleTileData template when user wants to pin (if WP7.8 or WP8) else StandardTileData
* When iterating tiles, I try CycleTileData template and failing that try StandardTileData for update

Code snippets that might help:

Add AppExtra above App element in WMAppManifest.xml file (works for both WP7.8 and WP8)

<AppExtra xmlns="" AppPlatformVersion="8.0">
  <Extra Name="Tiles"/>
</AppExtra>
public async Task DownloadFileAsync(string url, string filename, string folder = null)
{
    // create a web client for downloading the string
    var wc = new WebClient();

    try
    {
        IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

        string file = (folder == null ? filename : String.Format("{0}/{1}", folder, filename));
                
        using (Stream s = await wc.OpenReadTaskAsync(url))
        {
            using (Stream slocal = isf.OpenFile(file, FileMode.Create))
            {
                s.CopyTo(slocal);
            }
        }
    }
    catch (Exception ex)
    {
        if (1 == 1) // just to check exceptions during debugging. do whatever pleases you
        {
        }
    }
}

//works for both WP7.8 and WP8
private static Version TargetedVersion = new Version(7, 10, 8858);
public static bool IsTargetedVersion { get { return Environment.OSVersion.Version >= TargetedVersion; } }

private static void SetTileBackground(string[] filesToShow, string folder, Random random, ShellTile currentTile)
{
    bool tryFlip = false;

    if (Config.IsTargetedVersion)
    {
        try
        {
            Uri smallimage = new Uri("Images/CycleSmall.png", UriKind.Relative);
            Uri mediumimage = new Uri("Images/CycleMedium.png", UriKind.Relative);

            UpdateCycleTile(smallimage, mediumimage, folder, filesToShow, random, currentTile);
        }
        catch
        {
            tryFlip = true;
        }
    }
    else
        tryFlip = true;
            
    if(tryFlip)
    {
        int rand = random.Next(0, filesToShow.Length);

        StandardTileData NewTileData = new StandardTileData
        {
            BackBackgroundImage = new Uri(String.Format("isostore:{0}/{1}", folder, filesToShow[rand]), UriKind.Absolute)
        };

        currentTile.Update(NewTileData);
    }
}

public static void UpdateCycleTile(
    Uri smallBackgroundImage, Uri backgroundImage,
    string folder, string[] filesToShow, Random random, ShellTile currentTile)
{
    // Get the new cycleTileData type.
    Type cycleTileDataType = Type.GetType("Microsoft.Phone.Shell.CycleTileData, Microsoft.Phone");

    // Get the ShellTile type so we can call the new version of "Update" that takes the new Tile templates.
    Type shellTileType = Type.GetType("Microsoft.Phone.Shell.ShellTile, Microsoft.Phone");

    // Get the constructor for the new FlipTileData class and assign it to our variable to hold the Tile properties.
    var UpdateTileData = cycleTileDataType.GetConstructor(new Type[] { }).Invoke(null);

    // Set the properties. 
    SetProperty(UpdateTileData, "SmallBackgroundImage", smallBackgroundImage);

    Uri[] mediumImages = new Uri[9];

    mediumImages[0] = backgroundImage;
    for (int i = 1; i < 9; i++)
    {
        int rand = random.Next(filesToShow.Length);

        mediumImages[i] = new Uri(String.Format("isostore:{0}/{1}", folder, filesToShow[rand]), UriKind.Absolute);
    }

    SetProperty(UpdateTileData, "CycleImages", mediumImages);

    SetProperty(UpdateTileData, "Title", "my cineworld");
            
    // Invoke the new version of ShellTile.Update.
    shellTileType.GetMethod("Update").Invoke(currentTile, new Object[] { UpdateTileData });
}

private static void SetProperty(object instance, string name, object value)
{
    var setMethod = instance.GetType().GetProperty(name).GetSetMethod();
    setMethod.Invoke(instance, new object[] { value });
}

This by no means is fine / perfect code. Please treat it as a PoC and do whatever you do normally

Geolocator and MovementThreshold #wpdev #win8dev

Last few months, I have had too much on my plate. Been doing lot to Windows 8 and Phone development. Surprisingly Microsoft UK is keeping tabs on phone developers who aren’t adapting to #WP8 and seemingly, I was invited to a dev event targeting the likes of me :P

Sure I am going and in anticipation of the event, I decided to port Cineworld app to WP8. Its been a challenging task. Reworking a few bits of LongListSelector, Visual Studio / Blend disliking all the xaml and of course a button style causing xaml exception. If that wasn’t enough:

Having used Geolocator in Windows 8 app, I decided to use the same for WP8 as its usually a lot faster than GeoCoordinateWatcher. I moved the code to be more like Win8 and noticed that the location detection was flaky at best. Now I did the stupid thing and like in WP7 version, I decided to set both DesiredAccuracy to High and MovementThreshold to 0 thinking absolutely nothing.

Of course that didn’t help it, it made matters worse, instead of flaky behaviour, it decided to call it quits.

var pos = await locator.GetGeopositionAsync(TimeSpan.FromMinutes(5), TimeSpan.FromSeconds(2));

instead of timing out, it started to hang. In desperation, I started looking at other events exposed by this class and tried hooking into StatusChanged event. Now things were bad, I noticed that it was getting operation aborted exception and decided that something was seriously wrong and that I should take a nap instead :)

Of course the problem was still there when I woke up the next day :P its only later that I decided to search on Geolocation and operation aborted and realised that I wasn’t the only one and it was all my fault – causality of me setting the MovementThreshold to 0. I set it to 10 instead and bingo.. it all works.

While I didn’t find it, I hope this post helps people like an earlier post helped me.

MVVM and me – Part 2

I could have done this post yesterday but that would have been a long essay. Today we are going to look at displaying static data on XAML pages.

In C# when you have data that does not change, one tends to use const or static readonly. const causes compiler to replace all occurrences of variable usage with the actual data at compile time. That means you assemblies has no lookups at run-time. Static read-only is a static variable that can also be set in constructor – is read-only otherwise.

Now based on my previous experience doing WinForms and Webforms, normally I tend to set those directly in XAML. Say you want to content of a button or a textblock text (label). So the ideal way would be.

  1. Take View Model
  2. Define consts
  3. Set bindings to consts
  4. Compile and reload

Eureka.. there’s nothing..

Well XAML bindings make a big fuss of INotifyPropertyChanged interface. From sample I know that it works with properties so could it be that ?

Lets start:

  1. Take View Model
  2. Define consts
  3. Define properties
  4. Set property in the constructor to consts
  5. Set bindings to properties
  6. Compile and reload

There.. much better..

Lesson, const and compiler time optimisations are no good.. you need to define properties and additionally call PropertyChanged events and what not including set the properties at VM Creation in order to display data the proper MVVM way. A Single task of setting a text to a textblock or a button is translated into a handful tasks..

Update 1:
My friend @Scottisafool … suggested an alternative approach that he tends to use

  1. Define resources in App.xaml
  2. Set bindings to resources
  3. Compile and reload

This also works.. sure it means that all your strings are in one place but that’s still not MVVM
So it turns out there is not right way but there is a wrong way!! Everything else but code-behind as the last resource is the pukka MVVM way. Wrap up for today I think.

Update 2:
More messages suggesting that the mechanism to declare labels is to either hard code those or use Resources. That’s all fine.. I could use ResourceDictionary just in case the future me might want to localise the app.

That however still leaves the need to support of real consts impossible. There isn’t any support for those in bindings wrt View Model

MVVM and me – Part 1

As you know I recently joined a big name in Mobile Money business as a Senior Windows Developer. Part of that job involves working with others and not just doing WP Dev as a hobbyist (which I still do).

Most WP Devs are inherently XAML devs and they are well versed in MVVM (Model-View-View Model not necessarily in that order). MVVM itself is an extension of MVP (Model View Presenter) which to an extent has similarities to MVC (Model View Controller). Microsoft in .NET 2.0 started extensive work (crusade) against code behind. The idea that has been propagated has been to write less code – its more declarative and less code driven. (Use the system generated code since you are no good at it :) )

Personally I have never been a fan of declarative code. I do like XAML but only the extensible nature of it. how I just about use / contain and create controls with ease. Historically I am a middle-tier / server-side developer who loves not worrying about UI BS. I have spend years making code lean and that means adding layers that do little isn’t my cuppa tea.

However I am developing my next hobbyist app using MVVM. The next few blogs are doing to deal with my experiences moving from code driven to MVVM driven app development.

Before we get started just want to mention the fact that if I wasn’t doing the app in MVVM, I would have already finished it. Right now I am still doing XAML screens and battling myself almost constantly.

PhotoViewer with pinch & zoom, pan and flick support

A while back after scouring the net and merging some code, I created PhotoViewer that is used in my cool camera app. It might not be perfect but it works acceptably. Here’s how it work in code.

Lets start with Xaml..

<Image x:Name="imgViewer"  Stretch="UniformToFill" Width="728" Height="480">
    <Image.RenderTransform>
        <ScaleTransform x:Name="scaleTrans" ScaleX="1" ScaleY="1" />
    </Image.RenderTransform>
    <toolkit:GestureService.GestureListener>
        <toolkit:GestureListener Flick="GestureListener_Flick" 
            PinchStarted="GestureListener_PinchStart" 
            PinchDelta="GestureListener_PinchDelta" 
            PinchCompleted="GestureListener_PinchComplete"
            DragStarted="GestureListener_DragStart"
            DragDelta="GestureListener_DragDelta"
            DragCompleted="GestureListener_DragCompleted"
            Tap="GestureListener_Tap"
            DoubleTap="GestureListener_DoubleTap"/>
    </toolkit:GestureService.GestureListener>
</Image>

as you can see.. we start with Image and add a ScaleTransform. Next up with add GestureService from SL Toolkit. I am going to subscribe to some events. Here’s how the code behind looks

lets start by defining some data members

private readonly DispatcherTimer m_animationTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(10) };
private double m_friction = 0.99;
private Point m_scrollStartPoint;
private Point m_scrollTarget = new Point();
private double m_hvelocity;
private double m_vvelocity;
private double m_angle;
private double _cx, _cy;

Next up, set the Tick event in the constructor so we can do something on Tick of the DispatcherTimer.

m_animationTimer.Tick += new EventHandler(m_animationTimer_Tick);

Now the real code.. lets implement some of the event handlers

void m_animationTimer_Tick(object sender, EventArgs e)
{
    if (m_hvelocity < 0.1)
        m_hvelocity = 0;

    if (m_vvelocity < 0.1)
        m_vvelocity = 0;

    if (m_hvelocity == 0 && m_vvelocity == 0)
    {
        m_animationTimer.Stop();
        return;
    }

    if (m_angle > 0 && m_angle < 180)
        scaleTrans.CenterY -= m_vvelocity;
    else
        scaleTrans.CenterY += m_vvelocity;

    if(m_angle > 90 && m_angle < 270)
        scaleTrans.CenterX += m_hvelocity;
    else
        scaleTrans.CenterX -= m_hvelocity;
            
     m_hvelocity *= m_friction;
     m_vvelocity *= m_friction;

     if ((scaleTrans.CenterX <= 0 || scaleTrans.CenterX >= imgViewer.Width) || (scaleTrans.CenterY <= 0 || scaleTrans.CenterY >= imgViewer.Height))
     {
         if (scaleTrans.CenterX < 0)
             scaleTrans.CenterX = 0;

         if (scaleTrans.CenterX > imgViewer.Width)
             scaleTrans.CenterX = imgViewer.Width;

         if (scaleTrans.CenterY < 0)
             scaleTrans.CenterY = 0;

          if (scaleTrans.CenterY > imgViewer.Height)
              scaleTrans.CenterY = imgViewer.Height;

          m_animationTimer.Stop();
    }
}
        
private void GestureListener_Flick(object sender, FlickGestureEventArgs e)
{
    m_angle = e.Angle;

    m_animationTimer.Stop();

    m_scrollStartPoint = e.GetPosition(this);
    m_scrollTarget.X = m_scrollStartPoint.X + e.HorizontalVelocity;
    m_scrollTarget.Y = m_scrollStartPoint.Y + e.VerticalVelocity;
                
    m_hvelocity = Math.Abs(e.HorizontalVelocity)/100;
    m_vvelocity = Math.Abs(e.VerticalVelocity)/100;
                                
    if (m_scrollTarget.X < 0) 
        m_scrollTarget.X = 0;

    if(m_scrollTarget.X > imgViewer.Width)
        m_scrollTarget.X = imgViewer.Width;

    if (m_scrollTarget.Y < 0)
        m_scrollTarget.Y = 0;

    if (m_scrollTarget.Y > imgViewer.Height)
        m_scrollTarget.Y = imgViewer.Height;

    m_animationTimer.Start();
}

private void GestureListener_PinchStart(object sender, PinchStartedGestureEventArgs e)
{
    Point p1 = e.GetPosition(imgViewer, 0);
    Point p2 = e.GetPosition(imgViewer, 1);

    scaleTrans.CenterX = (p1.X + ((p2.X - p1.X) / 2));
    scaleTrans.CenterY = (p1.Y + ((p2.Y - p1.Y) / 2));

    _cx = scaleTrans.ScaleX;
    _cy = scaleTrans.ScaleY;
}

private void GestureListener_PinchDelta(object sender, PinchGestureEventArgs e)
{         
    // Compute new scaling factors
    double cx = _cx * e.DistanceRatio;
    double cy = _cy * e.DistanceRatio;

    // If they're between 1.0 and 4.0, inclusive, apply them
    if (cx >= 1.0 && cx <= 4.0 && cy >= 1.0 && cy <= 4.0)
    {
        if ((cy - 1) < 0.1 && (cx - 1) < 0.1)
            cx = cy = 1;
            
        scaleTrans.ScaleX = cx;
        scaleTrans.ScaleY = cy;
    }
}

private void GestureListener_PinchComplete(object sender, PinchGestureEventArgs e)
{
}

private void GestureListener_DragStart(object sender, DragStartedGestureEventArgs e)
{
}

private void GestureListener_DragDelta(object sender, DragDeltaGestureEventArgs e)
{
    scaleTrans.CenterX = (scaleTrans.CenterX - e.HorizontalChange);
    scaleTrans.CenterY = (scaleTrans.CenterY - e.VerticalChange);

    if (scaleTrans.CenterX < 0)
        scaleTrans.CenterX = 0;
    else if (scaleTrans.CenterX > (imgViewer.Height * scaleTrans.ScaleX))
        scaleTrans.CenterX = imgViewer.Height * scaleTrans.ScaleX;

    if(scaleTrans.CenterY < 0)
        scaleTrans.CenterY = 0;
    else if (scaleTrans.CenterY > (imgViewer.Height * scaleTrans.ScaleY))
        scaleTrans.CenterY = imgViewer.Height * scaleTrans.ScaleY;
}

private void GestureListener_DragCompleted(object sender, DragCompletedGestureEventArgs e)
{
    scaleTrans.CenterX = (scaleTrans.CenterX - e.HorizontalChange);
    scaleTrans.CenterY = (scaleTrans.CenterY - e.VerticalChange);

    if (scaleTrans.CenterX < 0)
        scaleTrans.CenterX = 0;
    else if (scaleTrans.CenterX > imgViewer.Width)
        scaleTrans.CenterX = imgViewer.Width;

    if (scaleTrans.CenterY < 0)
        scaleTrans.CenterY = 0;
    else if (scaleTrans.CenterY > (imgViewer.Height))
        scaleTrans.CenterY = imgViewer.Height;
}

private void GestureListener_DoubleTap(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
{
    scaleTrans.ScaleX = scaleTrans.ScaleY = 1;
}

private void GestureListener_Tap(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
{
    m_animationTimer.Stop();
    m_hvelocity = 0;
    m_vvelocity = 0;
}

HexColor for use with #wpdev and #win8dev

I found this code a while back and its been very handy at times. I have no idea where I found it so I apologise for not attributing it to the writer. Hope this is helpful to others as it has been to me.

public struct HexColour
{
    // Regex: This pattern matches hex codes in these two formats:
    // #000000 (no alpha value) and #FF000000 (alpha value at front).
    const string HEX_PATTERN = @"^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{8})$";

    const int LENGTH_WITH_ALPHA = 8;

    Color _color;

    public HexColour(string hexCode)
    {
        if (hexCode == null)
        {
            throw new ArgumentNullException("hexCode");
        }

        if (!Regex.IsMatch(hexCode, HEX_PATTERN))
        {
            throw new ArgumentException("Format must be #000000 or #FF000000 (no extra whitespace)", "hexCode");
        }

        // shave off '#' symbol
        hexCode = hexCode.TrimStart('#');

        // if no alpha value specified, assume no transparency (0xFF)
        if (hexCode.Length != LENGTH_WITH_ALPHA)
            hexCode = String.Format("FF{0}", hexCode);

        _color = new Color();
        _color.A = byte.Parse(hexCode.Substring(0, 2), NumberStyles.AllowHexSpecifier);
        if (_color.A < 50)
            _color.A = 50;
        _color.R = byte.Parse(hexCode.Substring(2, 2), NumberStyles.AllowHexSpecifier);
        _color.G = byte.Parse(hexCode.Substring(4, 2), NumberStyles.AllowHexSpecifier);
        _color.B = byte.Parse(hexCode.Substring(6, 2), NumberStyles.AllowHexSpecifier);
    }

    public byte A
    {
        get { return _color.A; }
        set { _color.A = value; }
    }

    public byte R
    {
        get { return _color.R; }
        set { _color.R = value; }
    }

    public byte G
    {
        get { return _color.G; }
        set { _color.G = value; }
    }

    public byte B
    {
        get { return _color.B; }
        set { _color.B = value; }
    }

    // Implicit cast from HexColor to Color
    public static implicit operator Color(HexColour hexColor)
    {
        return hexColor._color;
    }

    // Implicit cast from Color to HexColor
    public static implicit operator HexColour(Color color)
    {
        HexColour c = new HexColour();
        c._color = color;
        return c;
    }

    // Just like with Color, ToString() prints out the hex value of the
    // color in #ARGB format (example: #FF000000) by default.
    public override string ToString()
    {
        return ToString(true);
    }

    // I don't always need the alpha value, so I added an overload here
    // that lets me return the hex value in #RBG format (example: #000000).
    public string ToString(bool includeAlpha)
    {
        if (includeAlpha)
        {
            return _color.ToString();
        }
        else
        {
            return String.Format("#{0}{1}{2}", _color.R.ToString("x2"), _color.G.ToString("x2"), _color.B.ToString("x2"));
        }
    }
}

Happy coding

Async Task mechanism and OnNavigatedTo Part 2 #win8dev

Previously i discussed issues i had with #win8dev and #wpdev and using async task mechanism – http://invokeit.wordpress.com/2012/10/15/async-await-and-onnavigatedto-wpdev-win8dev/. With #wpdev you have to consume that mechanism as long as you use async CTP.

So how does one go about doing it in #win8dev #winrt correctly ? We start by marking all methods as async (in this case OnNavigatedTo. If we were firing mutilple calls and possibly making UI calls, #win8dev async implementations is a breeze.

AsyncDataSourceObj aeo = new AsyncDataSourceObj();
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    bErrored = false;
    try
    {
        MyDataType1 mydata1 = await aeo.UseAsyncAwaitStyleCall1();
        MyDataType2 mydata2 = await aeo.UseAsyncAwaitStyleCall2();
        MyDataType3 mydata3 = await aeo.UseAsyncAwaitStyleCall3();
    }
    catch
    {
        bErrored = true;
    }

    if(bErrored)
    {
        await (new MessageDialog("Error")).ShowAsync();
    }
    else
        // process data however you want.
}

above however isn’t a very good implementation as it chains various tasks. you dont want to do this unless the second call depends on the first etc. so if you have distinct calls, one can do this

AsyncDataSourceObj aeo = new AsyncDataSourceObj();
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    bErrored = false;
    try
    {
        List mytasklist = new List();
        mytasklist.Add(aeo.UseAsyncAwaitStyleCall1());
        mytasklist.Add(aeo.UseAsyncAwaitStyleCall2());
        mytasklist.Add(aeo.UseAsyncAwaitStyleCall3());

        await Task.WhenAll(mytasklist);
    }
    catch
    {
        bErrored = true;
    }

    if(bErrored)
    {
        await (new MessageDialog("Error")).ShowAsync();
    }
    else
        // process data however you want.
    // process data however you want.
}

the idea as explained to me by Oren after being told off by Matt is that you leave it to underlying implementation to use whatever it has rather than hacking around with it.

the code as a result is cleaner and works just as well :) What exactly does WhenAll do.. well it asks async task implementation to continue execution when all the tasks in the list are completed. The good part is that its a non blocking call. There’s also WhenAny which continues execution when one of the tasks in the list has completed.

Try and avoid WaitAny or WaitAll as both are blocking calls.

In case of #wpdev it implementation with async ctp was basic and one has to use hacks unforunately. we shall see what Async Targeting Pack brings to #wpdev party in a bit

Just for the record, you might not want to just chuck the exception away.. you should try and log it for future reference as it could be an issue thats just surfacing. have a look at MetroLog on nuget or if you like source, go github

Porting Windows Phone App to Windows 8 #wpdev #win8dev

The main message of HHGTG was “Don’t Panic”. It’s universally applicable and the case for porting you WP app to Windows 8 is no different. As WP Devs, we are already used to restrictions on what can and cannot be done. Windows 8 is a different beast that uses the same idea but being a full-blown OS, APIs exposed are different.

Windows Phone API is Silverlight API. Windows 8 has native support for XAML & HTML5. The API available to developers are WinRT and can be used from C++/CX, .NET and JS. I am going to discuss porting a C# Silverlight Windows Phone App to Windows 8. There are two parts to porting story. Get the code working and adapting the user interface. Getting the code working is the easy part. Adapting the UI slightly a bit tricky. Let’s get started

Code Porting – the easy way

Like many, I prefer to do just about everything the easy way. How do I go about it ? Well I take chunks of code and I move it between projects.

1) Custom Controls:

If you use custom controls, you might have to port some of them. A lot of controls have equivalents. If you use ListPicker or LongListSelector from Silverlight Toolkit, try ComboBox. I used AutoCompleteBox and had to write my own. If source is available, porting control is easy. In another project, I ported coding 4 fun toolkits Hexagon Color Picker.

2) XAML:

Start with the basic grid and build your xaml by pulling chunks from Windows Phone project. Most xaml with exception of certain controls can be copied. I have migrated storyboard animations etc no issues.

3) C# code:

    1. WinRT development like WP Dev requires use of asynchronous mechanism however the native WinRT API prefers to use async Task mechanism. Any methods making system calls need to be async and APIs need to be waited for.
      Read more about async programming on msdn http://msdn.microsoft.com/en-us/library/hh191443.aspx
    2. Storage:
      •   IsolatedStorageFile
      •   IsolatedStorageSettings
      public static void GetLevelData(DictionaryDef dict, int Level)
      {
          if (dict != DictionaryDef.NotSet)
          {
              App.WordList.Clear();
              App.WordDict.Clear();
      
              string File = GetLevelFile(dict, Level);
      
              Uri uriPaths = new Uri(File, UriKind.RelativeOrAbsolute);
      
              StreamResourceInfo sriPaths = System.Windows.Application.GetResourceStream(uriPaths);
      
      
              using (StreamReader sr = new StreamReader(sriPaths.Stream))
              {
                  string l;
                  while ((l = sr.ReadLine()) != null)
                  {
                      if (!String.IsNullOrWhiteSpace(l))
                      {
                          App.WordList.Add(l);
                          App.WordDict.Add(l, 0);
                      }
                  }
              }
          }
      }
      
      public class PersistHelper
      {
          public static T LoadObjectFromStorage<T>()
          {
              T ObjToLoad = default(T);
      
              try
              {
                  using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
                  {
                      if (isf.FileExists(GetFileName<T>()))
                      {
                          using (IsolatedStorageFileStream fs = isf.OpenFile(GetFileName<T>(), System.IO.FileMode.Open))
                          {
                              XmlSerializer ser = new XmlSerializer(typeof(T));
                              ObjToLoad = (T)ser.Deserialize(fs);
                          }
                      }
      
                  }
              }
              catch (Exception error)
              {
                  throw new NotImplementedException(error.Message);
              }
      
              return ObjToLoad;
          }
      
          public static void SaveObjectToStorage<T>(T ObjectToSave)
          {
              TextWriter writer;
      
              using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
              {
                  using (IsolatedStorageFileStream fs = isf.OpenFile(GetFileName<T>(), System.IO.FileMode.Create))
                  {
                      writer = new StreamWriter(fs);
                      XmlSerializer ser = new XmlSerializer(typeof(T));
                      ser.Serialize(writer, ObjectToSave);
                      writer.Close();
                  }
              }
          }
      
          public static string GetFileName<T>()
          {
              return typeof(T).FullName + ".xml";
          }
      
          public static bool IsObjectPersisted<T1>()
          {
              using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
              {
                  return isf.FileExists(GetFileName<T1>());
              }
          }
      
          public static T LoadSetttingFromStorage<T>(string Key)
          {
              T ObjToLoad = default(T);
      
              if (IsolatedStorageSettings.ApplicationSettings.Contains(Key))
              {
                  ObjToLoad = (T)IsolatedStorageSettings.ApplicationSettings[Key];
              }
      
              return ObjToLoad;
          }
      
          public static void SaveSettingToStorage(string Key, object Setting)
          {
              if (!IsolatedStorageSettings.ApplicationSettings.Contains(Key))
              {
                  IsolatedStorageSettings.ApplicationSettings.Add(Key, Setting);
              }
              else
              {
                  IsolatedStorageSettings.ApplicationSettings[Key] = Setting;
              }
          }
      
          public static bool IsSettingPersisted(string Key)
          {
              return IsolatedStorageSettings.ApplicationSettings.Contains(Key);
          }
      }
      
      •   StorageFile / StorageFolder.
      •   Get access to .NET streams using above
      •   Package.Current.InstalledLocation.Path – for   reading content files
      •   ApplicationData.Current provides LocalFolder,   RoamingFolder & TempFolder
      •   ApplicationData.Current provides LocalSettings   & RoamingSettings
      •   RoamingFolder / RoamingSettings shared between   devices.
      public static async void GetLevelData(DictionaryDef dict, int Level)
      {
          if (dict != DictionaryDef.NotSet)
          {
              App.WordDict.Clear();
      
              string File = Path.Combine(Package.Current.InstalledLocation.Path, GetLevelFile(dict, Level));
      
              StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(Path.GetDirectoryName(File));
      
              using (Stream s = await folder.OpenStreamForReadAsync(Path.GetFileName(File)))
              {
                  using (StreamReader sr = new StreamReader(s))
                  {
                      string l = null;
                      while (true)
                      {
                          l = sr.ReadLine();
                          if (l == null)
                              break;
      
                          if (l.Length > 0)
                              App.WordDict.Add(l, null);
                      }
                  }
              }
          }
      }
      
      public class PersistHelper
      {
          //private static StorageFolder storageFolder = Windows.Storage.ApplicationData.Current.RoamingFolder;
          //private static ApplicationDataContainer storageSettings = ApplicationData.Current.LocalSettings;
      
          private async static Task GetFileIfExistsAsync(StorageFolder folder, string fileName)
          {
              try
              {
                  return await folder.GetFileAsync(fileName);
      
              }
              catch
              {
                  return null;
              }
          }
      
      
          public static async Task LoadObjectFromStorage(Windows.Storage.StorageFolder storageFolder)
          {
              T ObjToLoad = default(T);
      
              try
              {
                  StorageFile storageFile = await storageFolder.CreateFileAsync(GetFileName(),
                      CreationCollisionOption.OpenIfExists);
      
                  using (Stream inStream = await storageFile.OpenStreamForReadAsync())
                  {
                      XmlSerializer serializer = new XmlSerializer(typeof(T));
                      ObjToLoad = (T)serializer.Deserialize(inStream);
                  }
              }
              catch (Exception error)
              {
                  throw new NotImplementedException(error.Message);
              }
      
              return ObjToLoad;
          }
      
          public static async void SaveObjectToStorage(T ObjectToSave, Windows.Storage.StorageFolder storageFolder)
          {
              string filename = GetFileName();
      
              using (Stream fs = await storageFolder.OpenStreamForWriteAsync(filename, CreationCollisionOption.ReplaceExisting))
              {
                  using (StreamWriter sw = new StreamWriter(fs))
                  {
                      XmlSerializer ser = new XmlSerializer(typeof(T));
                      ser.Serialize(sw, ObjectToSave);
                  }
              }
          }
      
          public static string GetFileName()
          {
              return typeof(T).FullName + ".xml";
          }
      
          public async static Task IsObjectPersisted(Windows.Storage.StorageFolder storageFolder)
          {
              string file = GetFileName();
      
              StorageFile storageFile = await GetFileIfExistsAsync(storageFolder, file);
      
              return (storageFile != null);
          }
      
          public static T LoadSetttingFromStorage(string Key, Windows.Storage.ApplicationDataContainer storageSettings)
          {
              T ObjToLoad = default(T);
      
              if (storageSettings.Values.ContainsKey(Key))
              {
                  using (StringReader sr = new StringReader((string)storageSettings.Values[Key]))
                  {
                      XmlSerializer serializer = new XmlSerializer(typeof(T));
                      ObjToLoad = (T)serializer.Deserialize(sr);
                  }
              }
      
              return ObjToLoad;
          }
      
          public static void SaveSettingToStorage(string Key, object Setting, Windows.Storage.ApplicationDataContainer storageSettings)
          {
              StringBuilder sb = new StringBuilder();
              using (StringWriter sw = new StringWriter(sb))
              {
                  XmlSerializer ser = new XmlSerializer(Setting.GetType());
                  ser.Serialize(sw, Setting);
              }
      
              if (!storageSettings.Values.ContainsKey(Key))
              {
                  storageSettings.Values.Add(Key, sb.ToString());
              }
              else
              {
                  storageSettings.Values[Key] = sb.ToString();
              }
      
          }
      
          public static bool IsSettingPersisted(string Key, Windows.Storage.ApplicationDataContainer storageSettings)
          {
              return storageSettings.Values.ContainsKey(Key);
          }
      }
      
    3. Playing Sounds
    4. Silverlight MediaElement
      XNA MediaPlayerSoundEffects
      XAML MediaElement
      MonoGame   (XNA) MediaPlayerSoundEffects
      SharpDX Managed   DirectX wrappers for C#
    5. Behaviours:
    6. No built in support for behaviours (unlike WP Blend support through Interactions lib)

      http://winrtbehaviors.codeplex.com provides DragFlickBehavior

    7. Navigation:
      • Use Frame class for navigation in WinRT. Exposes methods similar to those of NaviationService.
      • Frame does not support AddBackEntry and RemoveBackEntry
      • No Back button and associated event. Add backbutton or consume a xaml page other than Basic Page (all other pages derive from LayoutAwarePage) and a back button is added and is automatically bound to correct method.
    8. NavigationService.Navigate(new Uri("/GamePlay.xaml", UriKind.Relative));
      
      if(NavigationService.CanGoBack)
          NavigationService.GoBack();
      
      Frame.Navigate(typeof(GamePlay));
      
      if(Frame.CanGoBack)
          Frame.GoBack();
      

      Designing for Windows 8

      This is the difficult part and you get the hang of this after a few AEL sessions. Windows 8 app is more than just a port of Windows Phone app.

      1)      The screen real estate is only for your apps real consumer content.

      2)      Settings Pane is a single place to hold things relating to app configuration. App config, in app purchase into, privacy policy, about etc. all these are exposed by Settings Pane.

      3)      Use Settings Flyout (Callisto lib) to link individual item to Xaml content.. e.g. settings flyout to display app config.

      4)      Windows 8 apps do more than Portrait and Landscape modes. They have snapped and filled modes as well.

      5)      There is life outside Pivot and Panorama controls. Use FlipView, Grid, GridView, Semantic zoom etc so expose your content in the best way possible.

      6)      Take your time. Porting the 1st app is always difficult – it gets a lot easier going forward.

How to measure rendered string dimensions in #Win8Dev

While Windows 8 WinRT supports ViewBox control (its a control that allows text to auto resize depending upon available space), with my alarm clock app, I noticed substantial jittering (and resizing) as time changes between seconds. Of course you don’t want that happening.

The solution is to find optimum font size at start and then sticking with it until a resize is desired. Once you set the font family and font size to a textblock (tb), you can try getting its height / width.

With Windows Phone, the following would work well

this.tb.FontSize = 20;
double currentWidth = this.tb.ActualWidth;
double currentHeight = this.tb.ActualHeight;

This however does not work with Windows 8 / WinRT API. Here’s what you need to do

this.tb.FontSize = 20;
this.tb.Measire(new Size(400, 300)); // assuming that 400x300 is max size of textblock you want
double currentWidth = this.tb.DesiredSize.Width;
double currentHeight = this.tb.DesiredSize.Height;

Thats it really. I tend to increase / decrease font size depending upon need and only recalculated it if user wants a different font or changes the view (ie default to snapped etc)

The future of XNA development

Official Microsoft comments on XNA support so far has been that “XNA is fully supported” so existing games will work on WP8. however nothing was said about developing games for Windows Phone 8 in XNA. Today I explicitly asked this question and was clearly told NO.

This does make a lot of sense purely because Windows Phone 8 share codebase with Windows 8. The available choices for developing Metro-style apps for Windows 8 includes .NET, C++ / DX and HTML5 / JS. It does not include XNA. If that is true and accepted, we can also accept that Windows Phone 8 pure development (ie not targeting earlier platforms) will result in XNA not being available.

So where do that leave us.. According to Microsoft.. all engines and all big games companies wanted to stay native and hence the choice as such.. Considering most development on Windows Phone is hobbyist creation that seems a bit risky.. I don’t know many hobbyist developers who code C++ games.. XNA makes it easier and is an ideal choice… Of course it can be done in XAML / .NET..

The likely course of action short-term ? thank heavens that we have MonoGame.. They support for Windows 8 and I hope they will added support for pure Windows Phone 8. It allows you to write in XNA and it outputs WinRT compatible code (I presume using XAML /.NET or C++ / DX)

Let me know your thoughts on this..