Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

Windows Phone Page Lifecycle, Tombstoning and Data Caching

The title of this post sounds a little weird but is actually quite fundamental to how you develop for Windows Phone. Most training content/courses for Windows Phone seem to focus unnecessarily on the application wide events of launching, closing, activating and deactivating. These are useful to get an understanding of what tombstoning is and why it happens. However, in most cases what’s more important is knowing and understanding the page methods which you can override to intercept the page lifecycle, namely OnNavigatedTo and OnNavigatedFrom. These methods always occur as a pair and as such make a useful point at which to save and restore page data.

Let’s assume we now know that we are going to save and restore information in the OnNavigatedFrom and OnNavigatedTo. The next question is what data are we going to load and where to load it from. So now we need to look at different scenarios:

First time arriving at a page

The only thing you should rely on absolutely is the navigation uri for the page (look at the navigationeventargs). This should tell you all the information you need in order to load the data for the page. It might include a product id, a serialized object or some other identifier of the data you want to load.

Using the information from the navigation uri you then need to load the data for the page. This might come from:

- an in-memory application wide store (eg repository model)
- loaded from cached data on disk
- retrieve data from a service

Notice that these are in order of increasing latency. To make your applications appear more responsive you need to think about how you can cache content in memory and/or disk before calling out to a service

Leaving a page

When you leave a page there are two options:

- Forward navigation to some other page and/or application – in this case you need to cache the current data for the page in the State dictionary for the page. When the user comes back to the page, you should retrieve the information from the State dictionary and use it to populate the page. The advantage of the State dictionary is that it automatically handles Tombstoning for you!

- Backward navigation – in this case it’s up to you as to whether you cache the data or not. Caching the data has the advantage that if the use goes to that page again, the data can be loaded very quickly (eg browsing to the same news article again). You can’t use the built in page State dictionary for this because each time you navigate to a page, it will get an new State dictionary, so you’ll have to come up with your own caching mechanism.

Returning to a page

This is similar to arriving at a page, with the only exception that you need to look in the State dictionary first.

The important take away from this post is that looking up data should be a progressive action: start with the page State dictionary; then to an application wide in-memory cache; next look to disk; then call to a service.

Fiddler and Proxies for Windows Phone

This article from last year is a great starting point for addressing issues either with proxies or for accessing network traffic from the Windows Phone emulator: http://blogs.msdn.com/b/wsdevsol/archive/2013/06/05/configure-the-windows-phone-8-emulator-to-work-with-fiddler.aspx

Probably the missing piece for most people is step 4:

In the command windows on the bottom left corner of Fiddler type: prefs set fiddler.network.proxy.registrationhostname HostName where HostName is the name of your desktop computer

Then you can simply navigate to :8888/FiddlerRoot.cer">http://<yourhostmachinename>:8888/FiddlerRoot.cer to install the Fiddler root certificate (useful for SSL debugging!)

Visual States in Windows Phone and Windows Applications using MvvmCross

I’m a big fan of using Visual States defined in Blend to be able to see all the different states that a page/view within your application would look like under different conditions. Most of these conditions are reflected in the state of your view model. However, there is no built in mechanism for data binding to a visual state. There are a number of different ways to tackle this problem, for example data triggers to control state changes. On technique we’ve used quite successfully is to simply bubble up appropriate state changed events from the view model, which in turn triggers a state change at the page level. In this post I’m going to walk you through how we’ve extended MvvmCross to include our own base view model and base page which allows us to trigger and track the state of the page.

We’ll start by defining an interface which will be implemented by our base view model. This includes the StateChanged event and methods for invoking a state change, ChangePageState, and querying the current state, CurrentState. You’ll notice that these methods take a type parameter, this is so that we can use an enumeration, rather than string literals to define our states.

public interface IStateAndTransitions
{
    event EventHandler<DualParameterEventArgs<string, bool>> StateChanged;
    void ChangePageState<T>(T stateName, bool useTransitions = true) where T : struct;
    T CurrentState<T>() where T : struct;
}

Next, we’ll implement the IStateAndTransitions interface in our BaseViewModel class. This class also inherits from MvxViewModel, bringing with it all the goodness of MvvmCross.

public class BaseViewModel : MvxViewModel, IStateAndTransitions
{
    public event EventHandler<DualParameterEventArgs<string, bool>> StateChanged;

    private readonly Dictionary<string, string> currentStates = new Dictionary<string, string>();
    public T CurrentState<T>() where T : struct
    {
        var current = currentStates.SafeDictionaryValue<string, string, string>(typeof(T).FullName);
        var tvalue = current.EnumParse<T>();
        return tvalue;
    }

    public void ChangePageState<T>(T stateName, bool useTransitions = true) where T : struct
    {
        var current = currentStates.SafeDictionaryValue<string, string, string>(typeof(T).FullName);
        var newState = stateName.ToString();
        if (string.IsNullOrWhiteSpace(current) || current != newState)
        {
            currentStates[typeof(T).FullName] = newState;
            StateChanged.SafeRaise(this, newState, useTransitions);
        }
    }
}

The last thing to do is to extend the MvxPhonePage to wire up an event handler for the StateChanged event. The event handler simply invokes the state change by calling GoToState on the VisualStateManager.

public class BasePhonePage : MvxPhonePage
{

    protected IStateAndTransitions StatesAndTransitionsViewModel
    {
        get
        {
            return DataContext as IStateAndTransitions;
        }
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        var satvm = StatesAndTransitionsViewModel;
        if (satvm != null)
        {
            satvm.StateChanged += ViewModelStateChanged;
        }
    }

    private void ViewModelStateChanged(object sender, DualParameterEventArgs<string, bool> e)
    {
        //var controlName = e.Parameter1;
        var stateName = e.Parameter1;
        var useTransitions = e.Parameter2;

        // Locate the control to change state of (use this Page if controlNAme is null)
        Control control = this;
        VisualStateManager.GoToState(control, stateName, useTransitions);
    }

    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        var satvm = StatesAndTransitionsViewModel;
        if (satvm != null)
        {
            satvm.StateChanged -= ViewModelStateChanged;
        }

        base.OnNavigatedFrom(e);
    }
}

For completeness you’ll also need the parameter and dualparameter event args classes. These are used to make it easier to pass data values around when raising events.

public class ParameterEventArgs<T> : EventArgs
{
    public T Parameter1 { get; set; }

    public ParameterEventArgs(T parameter)
    {
        Parameter1 = parameter;
    }

  public static implicit operator ParameterEventArgs<T>(T parameter)
    {
        return new ParameterEventArgs<T>(parameter);
    }
}

public class DualParameterEventArgs<T1, T2> : ParameterEventArgs<T1>
{
    public T2 Parameter2 { get; set; }

    public DualParameterEventArgs(T1 parameter1, T2 parameter2):base(parameter1)
    {
        Parameter2 = parameter2;
    }

    public static implicit operator DualParameterEventArgs<T1, T2>(object[] parameters )
    {
        if(parameters==null || parameters.Length!=2) return null;
        return new DualParameterEventArgs<T1, T2>((T1)parameters[0], (T2)parameters[1]);
    }
}

Now, let’s see this in action in a view model, FirstViewModel:

public class FirstViewModel : BaseViewModel
{
    public enum FirstStates
    {
        Base,
        Loading,
        Loaded
    }

    public async Task LoadData()
    {
        ChangePageState(FirstStates.Loading);
        // Load some data (async to ensure no UI blocking)
        ChangePageState(FristStates.Loaded);
    }
}

Your page, FirstView, needs to inherit from BasePhonePage and have visual states called Loading and Loaded. The “Base” enumeration value is there just to represent the default state of the page. You should never have a state called “Base”, nor should you call ChangePageState with a value of Base. You can however, call CurrentState and compare the value to Base to see if a state has been set.

Hope this makes it easier for you to build your visual states in Blend.

Querying data from the Windows Phone and Windows Stores

We had a requirement today to query both the Windows Phone and Windows Stores for information about some of the apps we’ve been working on. Since both stores have a rich client interface it’s only natural that the store can be queried via a hidden pseudo api (“pseudo” because they’re more feed-like than a real api).

To work out how the api is structured the easiest thing to do is to setup Fiddler with SSL decoding and remote connections enabled on one computer and then on your Windows Phone and/or Windows 8 device you set the Fiddler computer to be the proxy. In order for this to work you’ll need to install the Fiddler certificate onto the device (Windows Phone installs the certificate correctly by default; Windows 8 you’ll need to put the certificate into the Trusted Root Certificate Authorities store for it to work).

Here’s what I pulled from my Windows Phone:

Application Info URL

http://marketplaceedgeservice.windowsphone.com/v8/catalog/apps/{app guid}?os=8.0.10211.0&cc=AU&lang=en-US

Replace “app guid” with the Guid for your application. You can find the Guid for your application by finding the application in the web version of the Windows Phone Store and then looking in the address bar.

Image URL

http://cdn.marketplaceimages.windowsphone.com/v8/images/{image guid}?hw=486577666&imagetype=icon_small

Replace “image guid” with the Guid for the image you want to retrieve. The image Guids are listed in the information returned from the application info URL.

 

Here’s what I pulled from my Windows 8 device:

Application Info URL

https://next-services.apps.microsoft.com/browse/6.3.9600-0/776/en-GB_en-AU.en-US.en/c/AU/cp/10005001/Apps/{app guid}

Replace “app guid” with the Guid for your application. You can find the Guid for your application by finding the application in the web version of the Windows Store and then looking in the address bar.

Image URL

http://wscont1.apps.microsoft.com/winstore/1.4x/{image path}

Replace “image path” with the relative path to the image that you want which can be found in the Application Info URL

Boosting Reviews of your Windows Phone Application using the MarketplaceReviewTask Launcher

One thing that so many developers forget is that reviews are a crucial element in driving the adoption of your application. Not only do a lot of developers forget to provide a link to submit a review within their application, they also don’t prompt the user to post a review. Here’s a simple suggestion that should help drive reviews:

- Make sure the user can navigate to the Windows Phone Store review page for your application from somewhere within your application

- Prompt the user to complete a review based on some algorithm eg:

         > After X days of using the app

         > After running the app X number of times

         > After successfully completing something within the app

The simplest way to navigate users to the review page is using the MarketplaceReviewTask:

MarketplaceReviewTask marketplaceReviewTask = new MarketplaceReviewTask();
marketplaceReviewTask.Show();

Windows Store In App Purchase ArgumentException when calling LoadListingInformationAsync

When you couple poor API documentation with dumb developer decisions you can cause developers to waste hours trying to diagnose issues with their apps. We’ve just tracked down an issue with calling CurrentApp.LoadListingInformationAsync from a Windows Store application we’re building. Whilst calling the same method on the CurrentSimulatorApp works without throwing exception, calling the method on CurrentApp throws an ArgumentException with message "Value does not fall within the expected range."

Initially we thought that this issue was related to the app not being published in the Store, so we submitted and published the app. Unfortunately the exception continues….

This thread: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/0de52a76-2ec3-4b82-8d38-7385f22132f0/currentapploadlistinginformationasync-throws-argumentexception

holds the answer – you need to call this method from the UI thread.

Points to remember when building an API:

- You shouldn’t design an API that needs to run on the UI thread, that isn’t UI related

- You should document possible exceptions

- If you’re going to provide a simulator API

    - The simulator should implement an interface so it can be mocked properly

    - The simulator should mirror the behaviour of the real thing (in throw similar exceptions!)

Windows Phone goes BIG with 1080p resolution

Windows Phone 8 applications will, out of the box, automatically scale on these high resolution devices. But what if you want to make use of this extra resolution, particularly on larger devices such as the Lumia 1520. Here are some links to some useful guidance on how you can take advantage of the extra space:

Taking Advantage of Large-Screen Windows Phones

Porting Existing Apps to large Screen Device

Simulate 1080p windows phone emulator

Windows Phone Application Testing

Here’s a couple of useful links on testing for Windows Phone applications:

Unit testing for Windows Phone apps

Options for publishing Windows Phone beta apps and testing in-app purchase

Nokia: Remote Device Access

One additional comment I would make about unit testing for Windows Phone is that unfortunately the tests written using a Visual Studio Windows Phone unit testing project can’t be executed (easily) as part of a Visual Studio Online automated build. The work around for this is to place most of your business logic in a Portable Class Library and to simply use a regular unit testing project to test the functionality. Of course, this isn’t as accurate as testing using either the emulator or a real device but it will give you some level of regression testing with each build (ideally after each check in).

Conditional Includes with Visual Studio Project Files

Often during development your application may be set to connect to a dev or test set of services. When you go to release your application you’ll then switch to point to the production or live set of services. A common way to do this is to define a constant which is the base url for the services and then use the DEBUG conditional compilation constant to control what the value of the constant is. For example

public static class Contants
{
#if DEBUG
    public const string BaseUrl = "
http://test.apiservice.com";
#else
    public const string BaseUrl = "
http://production.apiservice.com";
#endif
}

This is a simple but effective strategy to control which services are used based on build configuration. If you select a Debug build, you’ll connect to the test services; the Release build will connect to the production services. This strategy also keeps the differences between a debug and release build to a minimum, since all that is changing is the base url for the service. However, this simplicity can lead to some confusion as it can be hard to tell whether you’re using a debug or release build of an application.

One work around for this is to surface up the base url in the UI, for example in the About page, so that you can tell which version of the app is running. Another alternative is to customise the default tile for the application so that it is clear which build is installed. This can be done by dynamically switching between multiple image files during the build process.

Let’s start by creating our two live tiles (one for debug, one for release):

FlipCycleTileMedium FlipCycleTileMedium

Create the following folder structure in the solution folder:

\DefaultTiles
         \Debug
               FlipCycleTileMedium.png
         \Release
               FlipCycleTileMedium.png

Place the created images into the appropriate folder – note that they should have the same file name.

In Visual Studio, right-click on the project node and select “Unload Project”. Then right-click the project node again and select Edit. Locate where the live tile image is included eg:

<Content Include="Assets\Tiles\FlipCycleTileMedium.png">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

And replace it with the following xml

<Content Include="..\DefaultTiles\$(Configuration)\FlipCycleTileMedium.png">
  <Link>Assets\Tiles\FlipCycleTileMedium.png</Link>
  <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>

This xml links in the appropriate file based on the $(Configuration) parameter. Save and reload the project. Now as you switch build configurations you’ll see that the appropriate live tile image is included. You can check this by either deploying the application to a device/emulator, or by checking the output folder where you’ll see the appropriate file appear after the build has completed.

App Generators: Windows Phone App Studio and Project Siena

With all the recent interest in app generators by Microsoft, I’m wondering whether there is going to be a run on app-kiddies (kick back to “script kiddies” who plagued the internet a decade or so ago): Application builders who don’t have a clue how to write an application but seem to be able to coble together a number of applications, that all look surprisingly similar, using generators.

The two app generators I’m referring to are:

Windows Phone App Studio

“Take your app from idea to Windows Phone in record time”

Microsoft Project Siena (Beta)

“Unleash your expertise and imagination”

Having checked out the capabilities of these generators I don’t feel that my job as a Windows platform developer is in jeopardy. In fact, I think these generators allow would-be app creators to get started with the basics. Once they hit the limitations of the tools, that’s when they can come to us to fill out the gaps. This is a great way to test a concept, or two, before over-investing in any particular idea.

Windows and Windows Phone app convergence

One of the things that is becoming apparent is that the convergence between Windows and Windows Phone applications it a hot topic. Developers often ask why we have two development platforms to target, where as iOS and Android only have the one. For example iOS you can build a single package which includes both iPad and iPhone versions of an application. This argument is of course completely flawed since we’re comparing apples and oranges. If you widen the scope to include Mac development then those in the Apple world also have to target two platforms. This argument doesn’t really apply to Android since it doesn’t really feature in the desktop space.

What we are seeing is that we can increasingly share resources between our Windows and Windows Phone applications. The continual evolution of Portable Class Libraries mean that we can build reusable libraries that will work without recompilation across both Windows and Windows Phone applications. In fact you can even use these libraries in your iOS and Android projects, assuming you’re using Xamarin as your cross platform approach.

Unfortunately all this discussion of convergence at an dev platform layer completely ignores what’s going on at the user experience level. The reality is that you don’t need technology convergence in order to build a consistent user experience across both platforms. What’s been interesting to watch is how Microsoft tries to converge the look of Windows and Windows Phone first party applications. Whilst  both interfaces are laced with the essence of Metro Modern UI, there are some significant differences between them.

Take for example the Hub/Panorama experience – Windows 8 didn’t have a control for this, where as Windows Phone has the Panorama control; Windows 8.1 now has the Hub control which makes it easier for developers to build a hub style experience. The Hub and Panorama controls aren’t the same eg the hub control typically has a hero pane, where as the panorama has a background image which has parallax scrolling.

If you look at some of the Microsoft applications, such as Bing News, you’ll see that they’ve taken UX convergence to the next level, attempting to minimize any difference between the platforms. Below you can see the Windows Phone Bing News app, followed by the Windows version.

1 of 6 2 of 6 3 of 6

 

Screen shot 1

The question you should be asking (and Microsoft should be answering) is whether you should be sticking to the standard Panorama look and feel, or should you be trying to match what Bing News is doing and aligning with the Windows Hub control?

Windows 8.1, the Hub Control and Visual States

The more I use the Windows 8.1 Hub control the more I get frustrated by it. In my previous post Databinding with the Windows 8.1 Hub control, I talked about getting data binding to work. This is useful if you’re going to have a series of panes all with similar structure. However, you could probably get the same effect using grouping in a GridView. A more common scenario is to have a number of different panes, which hold content coming from different sources. In this case, each pane is going to be loading data independently and you’ll probably want each pane to have different visual states representing loading, data loaded successfully, data load failed, data loaded successfully but no data available etc. If we were building this using the Panorama control for Windows Phone, or using the deprecated method of a horizontal stack panel inside a scrollviewer, then we could simply drop in a couple of extra elements and then control which ones are visible using visual states. As the view model for the page is typically responsible for controlling the loading of content across each of the panes (it simply loads the data, and data binding does the rest), it is also responsible for controlling the visual states across the page. Unfortunately this doesn’t work with the Hub control – the contents

As a starting point for this post I’m going to use the source code sample from the article States, Navigation and Testing with Portable Class Libraries for Windows Phone, as this will give us the basic infrastructure for raising state changed events from our view model. I won’t go through the details of wiring up the Windows application to use the locator  pattern – it’s essentially the same as for Windows Phone. What we will be focussing on is the hub control and how we can use state change events to control the content for each pane. The Panorama control used in Windows Phone applications, is made up of PanoramaItems and the contents of each pane is simply added as content. The Hub control is made up of HubSections but the contents for each pane is added into a data template, similar to the following:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:userControls="using:StatesAndNavigation.Win.UserControls"
      x:Class="StatesAndNavigation.Win.MainPage"
      DataContext="{Binding Main, Source={StaticResource Locator}}"
      mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Hub>
            <HubSection>
                <DataTemplate>
                …
                </DataTemplate>
            </HubSection>
        </Hub>
    </Grid>
</Page>

Initially this works fine and Blend can be used to design each HubSection. However, if you attempt to wire up visual states which need to reference elements inside the datatemplate you’ll discover it won’t work. For example you might want to have different content for loading and then when the data has loaded. One solution is to create a usercontrol which has these states:

<UserControl x:Class="StatesAndNavigation.Win.UserControls.MainFirstPaneUserControl"
             xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             d:DesignHeight="300"
             d:DesignWidth="400">

    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="LoadingStates">
                <VisualState x:Name="Loading">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                       Storyboard.TargetName="SP_Loading">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <Visibility>Visible</Visibility>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(ProgressRing.IsActive)"
                                                       Storyboard.TargetName="progressRing">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <x:Boolean>True</x:Boolean>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Loaded">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                       Storyboard.TargetName="GD_Loaded">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <Visibility>Visible</Visibility>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="NotAbleToLoad">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                       Storyboard.TargetName="GD_NotAbleToLoad">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <Visibility>Visible</Visibility>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <StackPanel x:Name="SP_Loading"
                    Visibility="Collapsed">
            <TextBlock Text="Loading...."
                       FontSize="48" />
            <ProgressRing x:Name="progressRing"
                          Width="50"
                          Height="50" />

        </StackPanel>
        <Grid x:Name="GD_Loaded"
              Visibility="Collapsed">
            <TextBlock Text="All data loaded"
                       FontSize="48" />
        </Grid>
        <Grid x:Name="GD_NotAbleToLoad"
              Visibility="Collapsed">
            <TextBlock Text="Not able to load"
                       FontSize="48" />
        </Grid>
    </Grid>
</UserControl>

This usercontrol would then be added to the datatemplate for the hubsection:

<HubSection>
    <DataTemplate>
        <userControls:MainFirstPaneUserControl />
    </DataTemplate>
</HubSection>

The issue is that we need some mechanism for triggering the visual state change from the view model for the page. In the same way as the page wires an event handler for the StateChanged event on the viewmodel, the usercontrol also has to wire up to this event. As the usercontrol inherits the DataContext from the page, the usercontrol can listen to the DataContextChanged event and wire up to the StateChanged event at that point.

public sealed partial class MainFirstPaneUserControl
{
    public MainFirstPaneUserControl()
    {
        InitializeComponent();

        DataContextChanged += MainFirstPaneUserControl_DataContextChanged;
    }

    void MainFirstPaneUserControl_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
    {
        var ctrl = sender as MainFirstPaneUserControl;
        ctrl.WireStateChanged();

    }

    private void WireStateChanged()
    {
        ViewModel.StateChanged += ViewModelStateChanged;
    }

    private void ViewModelStateChanged(object sender, StateChangedEventArgs e)
    {
        VisualStateManager.GoToState(this, e.StateName, e.UseTransitions);
    }

    private BaseStateChange ViewModel
    {
        get
        {
            return DataContext as BaseViewModel;
        }
    }
}

This appears to work, except the initial state changed event is skipped. The Hub, by design, lazy loads the hubsections, meaning that the OnNavigatedTo for the page gets run before the hubsection has been created and wired up. To resolve this problem the view model needs to track the current visual state:

public event EventHandler<StateChangedEventArgs> StateChanged;
private readonly Dictionary<Type,object> currentState = new Dictionary<Type, object>();
protected void OnStateChanged<T>(T state, bool useTransitions = true) where T : struct
{
    currentState[typeof (T)] = state;

    if (StateChanged != null)
    {
        StateChanged(this, new StateChangedEventArgs { StateName = state.ToString(), UseTransitions = useTransitions });
    }
}

public T CurrentState<T>()
{
    object current;
    currentState.TryGetValue(typeof (T), out current);
    return (T) current;
}

And the usercontrol needs to query it at the point the state changed event is wired up:

private void WireStateChanged()
{
    var current = ViewModel.CurrentState<MainViewModel.LoadingStates>();
    if (current != MainViewModel.LoadingStates.Base)
    {
        VisualStateManager.GoToState(this, current.ToString(), false);
    }
    ViewModel.StateChanged += ViewModelStateChanged;
}

When we run this, we’ll see the visual state for the hubsection switch between loading and loaded states.

image     image

Download the code

Databinding with the Windows 8.1 Hub control

One of the controls that was introduced with Windows 8.1 is the Hub control. This control is fantastic as it provides a great starting point for application developers to build applications that use the default L structure common to most Windows 8 style applications. Visual Studio 2013 comes with a dedicated Hub project template which is a useful starting point but the XAML Hub Control Sample is an even better resource in terms of getting familiar with the control. It includes:

  • Basic usage.
  • Adding an image in a section which displays from edge to edge of the screen.
  • Adding interactive headers.
  • Adding semantic zoom.
  • Adding a vertical layout.

     

    Specifically if you looking to replicate the structure of any of the Bing apps (eg Bing News) where there is a Hub experience and Semantic zoom to jump through sections, this sample is the place to start.

    There are however two areas where this control is just plain awful and no consideration was given to how the control was to be used in practice:

    1) Support in Blend is woeful. Each hub section  has to be developed as a content template which is fine, except that you then can’t use visual states to control layout changes within a hub section. This is just plain disappointing.

    2) Minimal data binding support. Yes, you can set data context and data bind individual sections but unlike the gridview/listview which support grouping, the Hub control doesn’t support data binding the sections to a data source. If you look at the Panorama or Pivot controls on Windows Phone if you have a collection of sections, you can data bind this to the ItemsSource property which will dynamically create the appropriate number of panoramaitem or pivotitems. No such luck (unless I missed something) with the Hub control.

    The good news is that it’s not that hard to build a DYI data binding solution. Here’s a snippet that’ll get you started:

    public class HubBinder : DependencyObject
    {
        public static readonly DependencyProperty HeaderTemplateProperty = DependencyProperty.RegisterAttached(
            "HeaderTemplate",
            typeof(DataTemplate),
            typeof(HubBinder), new PropertyMetadata(null, HeaderTemplateChanged)
            );

        private static void HeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var hub = d as Hub;
            if (hub == null) return;
            var template = e.NewValue as DataTemplate;
            if (template == null) return;
            foreach (var hubSection in hub.Sections)
            {
                hubSection.HeaderTemplate = template;
            }
        }
        public static void SetHeaderTemplate(UIElement element, DataTemplate value)
        {
            element.SetValue(HeaderTemplateProperty, value);
        }

        public static DataTemplate GetHeaderTemplate(UIElement element)
        {
            return element.GetValue(HeaderTemplateProperty) as DataTemplate;
        }

        public static readonly DependencyProperty SectionTemplateProperty = DependencyProperty.RegisterAttached(
            "SectionTemplate",
            typeof(DataTemplate),
            typeof(HubBinder), new PropertyMetadata(null, SectionTemplateChanged)
            );

        private static void SectionTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var hub = d as Hub;
            if (hub == null) return;
            var template = e.NewValue as DataTemplate;
            if (template == null) return;
            foreach (var hubSection in hub.Sections)
            {
                hubSection.ContentTemplate = template;
            }
        }
        public static void SetSectionTemplate(UIElement element, DataTemplate value)
        {
            element.SetValue(SectionTemplateProperty, value);
        }

        public static DataTemplate GetSectionTemplate(UIElement element)
        {
            return element.GetValue(SectionTemplateProperty) as DataTemplate;
        }
        public static readonly DependencyProperty DataSourceProperty = DependencyProperty.RegisterAttached(
            "DataSource",
            typeof (object),
            typeof (HubBinder), new PropertyMetadata(null, DataSourceChanged)
            );

        private static void DataSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var data = e.NewValue as IEnumerable;
            var hub = d as Hub;
            var template = GetSectionTemplate(hub);
            var header = GetHeaderTemplate(hub);
            if (data == null || hub == null) return;
            foreach (var section in data)
            {
                var sect = new HubSection { DataContext = section, ContentTemplate = template, HeaderTemplate = header };
                var hubData = section as IHubData;
                if (hubData != null)
                {
                    sect.Header = hubData.Header;
                    }

                hub.Sections.Add(sect);
            }
        }

        public static void SetDataSource(UIElement element, object value)
        {
            element.SetValue(DataSourceProperty, value);
        }

        public static object GetDataSource(UIElement element)
        {
            return  element.GetValue(DataSourceProperty);
        }
    }

    public interface IHubData
    {
        object Header { get; }

    }

    To use this attached property you simply need to add the DataSource attribute to your Hub control and create a data template called HubSectionTemplate:

    <Page x:Class="App2.MainPage"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:local="using:App2"
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          mc:Ignorable="d">
        <Page.Resources>
            <DataTemplate x:Key="HubSectionTemplate">
                <StackPanel>
                    <TextBlock Text="{Binding Content}"
                               FontSize="26.667"
                               Foreground="#FF1133A6" />
                </StackPanel>
            </DataTemplate>
            <DataTemplate x:Key="HubHeaderTemplate">
                <StackPanel>
                    <TextBlock Text="{Binding}"
                               FontSize="40"
                               Foreground="White" />
                </StackPanel>
            </DataTemplate>
        </Page.Resources>

        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <Hub local:HubBinder.DataSource="{Binding Sections}"
                 local:HubBinder.SectionTemplate="{StaticResource HubSectionTemplate}"
                 local:HubBinder.HeaderTemplate="{StaticResource HubHeaderTemplate}">

            </Hub>
        </Grid>
    </Page>

    It’s definitely not a fully fledged data binding solution but it should be enough to get those who are stuck looking up and running. The view model for the page could then look like:

  • public class MainViewModel
        {
            private ObservableCollection<Section> sections = new ObservableCollection<Section>();

            public ObservableCollection<Section> Sections
            {
                get
                {
                    return sections;
                }
            }
        }

        public class Section:IHubData
        {
            public string Title { get; set; }
            public string Content { get; set; }

            public object Header
            {
                get
                {
                    return Title;
                }
            }
        }

    3D Motion, a Bogus iOS7 Feature, implemented in 50 lines of code on Windows Phone 8

    After playing with iOS7 for a little, I was curious about the new 3D effect they have going on the home screen. For those familiar with Windows Phone you’ll already be familiar with the parallax effect that is used within the Panorama control to give the idea of motion. So, I’m thinking it can’t be that hard to produce the same sort of effect using the gyroscope capability coupled with a simple render transform or two.

    A few minutes later I’ve got the following code which produces a similar effect to what you’d see on iOS7:

    Motion sensor = new Motion();
    public MainPage()
    {
        InitializeComponent();
     
        sensor.CurrentValueChanged += sensor_CurrentValueChanged;
        sensor.Start();
    }
     
    private ManualResetEvent waiter=new ManualResetEvent(false);
    void sensor_CurrentValueChanged(object sender, 
         SensorReadingEventArgs<MotionReading> e)
    {
        try
        {
            var pitch = e.SensorReading.Attitude.Pitch;
            var roll = e.SensorReading.Attitude.Roll;
     
            Dispatcher.BeginInvoke(() =>
                {
                    var transform = B_Background.RenderTransform as CompositeTransform;
                    var contentTransform = GD_Content.RenderTransform as CompositeTransform;
                        var newTrans =  24*roll*2/Math.PI;
                        var contentShift = 18 * roll * 2 / Math.PI;
                    transform.TranslateX = 
                    -Math.Max(Math.Min(newTrans, 50),-50);
                    contentTransform.TranslateX = 
                    Math.Max(Math.Min(contentShift, 12), -12); 
     
                    newTrans = 48*pitch*2/Math.PI;
                    contentShift = 36 * pitch * 2 / Math.PI;
                    transform.TranslateY = 
                    -Math.Max(Math.Min(newTrans, 50), -50);
                    contentTransform.TranslateY = 
                    Math.Max(Math.Min(contentShift, 12), -12); 
                    waiter.Set();
                });
            waiter.WaitOne();
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }

     

    It’s not that easy to demonstrate this via a blog but in the following images you can see the slight displacement of the background and the foreground icons as the screen is rotated through different pitch and yaw values.

    image image image

    Full source:

    TTF Font with Windows Phone 8

    This is the story of a stubborn font (.ttf) that refused to work in a Windows Phone 8 application…. It all starts with a simple Windows Phone 7 application where the font works fine. Let’s just recall on how you can include a custom font within your application:

    Option 1 – Build action = Content

    - Add the TTF file (in this case Colonna.TTF, which is the Colonna MT Regular font) to your project by right-clicking the project in solution explorer and select Add > Existing Item. Select the TTF file and click OK

    - Select the TTF file you just added and make sure the Build Action is set to Content (you can optionally set the Copy to Output Directory if you want but this actually isn’t required as the file will be copied regardless if it’s set to Content for a Windows Phone project)

    image

    Next, we just need to add a bit of XAML to display the font within our application:

    <TextBlock Text="Test Text with Custom Font" 
                       FontFamily="Colonna.ttf#Colonna MT" />

     

    It’s worth breaking the FontFamily attribute value into its parts. Before the # is the path to the TTF file. If you put the TTF file in a folder or in a different assembly you’ll need to adjust the path accordingly. After the # is the name of the font. This can be found by opening the TTF file from Windows Explorer using the default Windows Font Viewer:

    image

     

    Option 2 – Blend Embedded Font

    An alternative is to get Blend to do the hard work for you. Switch to Blend (if you’re not already designing your application in Blend then you should be!) and select the TextBlock where you want to use the custom font. In the Properties window locate the Text property group (you can type “font” in the search box to reduce the list of properties). From the FontFamily dropdown, click on the Font Manager button:

    image 

    Select the font that you want to embed in your application, in this case Bradley Hand ITC, and click OK

    image

    You will see that this font has been added to a Fonts folder in the Projects window:

    image

    Now from the FontFamily dropdown you can select the font and you’ll notice that it has an icon next to it indicating that the Font has been added to the project.

    image

    An alternative is to select the font and then check the “Embed” checkbox in the Text group:

    image

    What’s interesting is that the syntax for using this font in the application is slightly different

    <TextBlock Text="Test Text with Embedded Custom Font" 
                       FontFamily="/TestFont;component/Fonts/Fonts.zip#Bradley Hand ITC" />

    By default Blend specifies the font family using an absolutely path. A relatively path will work just as well, for example:

    <TextBlock Text="Test Text with Embedded Custom Font" 
               FontFamily="Fonts/Fonts.zip#Bradley Hand ITC" />

     

    If you switch across to Visual Studio you’ll see that the TTF file has been included with a Build Action set to BlendEmbeddedFont.

    image

    Warning: it’s not enough to simply add a TTF file into your application and set the build action to BlendEmbeddedFont. In this scenario, where we embedded the font via Blend, some additional attributes were also set that you don’t see in the Properties window (these are not set when you simply change the Build Action to BlendEmbeddedFont and are required for the font to be correctly embedded).

    <BlendEmbeddedFont Include="Fonts\BRADHITC.TTF">
          <IsSystemFont>True</IsSystemFont>
          <All>True</All>
          <AutoFill>True</AutoFill>
          <Uppercase>True</Uppercase>
          <Lowercase>True</Lowercase>
          <Numbers>True</Numbers>
          <Punctuation>True</Punctuation>
        </BlendEmbeddedFont>

     

     

    Windows Phone 8 and the Stubborn Font

    Both of the options presented in the previous section worked brilliant for my font in a Windows Phone 7 project. Unfortunately when I upgraded my application to Windows Phone 8 the font stopped rendering – the TextBlock elements would revert to using the default font.

     

    Attempt 1: Adjusting legal rights for embedding

    After talking with a few people about what the cause of the issue could be (ie not following options 1 or 2 above) it was suggested (thanks Vaughan from Bitrave) that it was font licensing issue. Apparently, which I didn’t realise there is a flag in the TTF file which indicates whether the font can be embedded or not. There are a couple of rudimentary tools out there that will allow you to tweak this (and yes, I have permissions from the font designer to do this!). The one I used was TTFEdit.

    http://sourceforge.net/projects/ttfedit/

    What astounded me was that this was a Java application…. which meant I needed to install the JRE… ummm, where do I get that again, oh, right, Java.com of course:

    http://java.com/en/download/index.jsp

     

     

     

     

     

     

     

     

     

     

     

    Do you think installing this is enough… no, because it doesn’t add itself to the path. I then had to add c:\Program Files (x86)\Java\jre7\bin to my path so it was accessible from my command prompt:

    image

     

    Ok, now we’re ready to run TTFEdit: Open a command prompt, navigate to the directory where you extracted TTFEdit (it comes as a zip file, so don’t forget to unblock it before extracting it), and execute “Run.cmd” – this will launch the UI:

    - File > Open > Select your TTF file

    - View > Show Advanced

    image

    - Select the OS/2 tab and look for the “Legal rights for embedding” field. Hover over the text box and you’ll see the tooltip that indicates possible values. You’ll notice that the Colonna MT has been set to 8 which means it can be embedded.

    image

    I’ve tried setting this attribute to all sorts of different values and it appears that Visual Studio, Blend and Windows Phone completely ignores them (ie with the Colonna font I couldn’t get it to not show the font). I’ve also tried adjusting my rogue font (default value was 0 which should afaik allow embedding anyhow) but couldn’t get it to render. Looks like this isn’t the answer!

     

    Attempt 2: Issue with file format

    Whilst it appears that Windows can open my rogue font and install it correctly, the font did originate from a Mac. A couple of the tools I tried for attempt 1 indicated that they could access or read one of the tables in the TTF file – this made me wonder whether there was something slightly screwy in the file which was causing Windows Phone not to handle the file correctly.

    I found a GUI tool called BirdFont (http://birdfont.org/) which can be used to edit TTF files. Interestingly it’s also a Java application (I can’t recall the last time I used a Java application and now to have two in a day….).

    I simply opened my TTF file, switched to the Menu tab, gave it a new name  and clicked Export.

    image

    This generated a new TTF which worked perfectly in my Windows Phone 8 application. I’m yet to work out exactly what the differences are but if we open both fonts in TTFEdit the OS/2 table version is different (and if you recall from earlier the OS/2 table version of the Colonna font was 1). I’d be interested to know exactly what the limitations of TTF font support on Windows Phone is but at least I have a work around for when I do come across a font that doesn’t want to play ball.

    For reference, here’s the link to what I could find on MSDN that talks about font support for Windows Phone ( http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202920(v=vs.105).aspx#BKMK_FontEncoding)

    Introduction To Data Binding for Windows and Windows Phone (part 1)

    Introduction To Data Binding for Windows and Windows Phone (part 2) >>

    Given how long Microsoft has been using XAML in one shape or another across a range of technologies (WPF, Silverlight, Windows Phone, XBox, Windows 8) it still surprises me how often I get asked about data binding. In this series we’re going to go back to basics and take a look at how to use data binding within you Window 8 and Windows Phone application. For the most part I’ll focus on Windows Phone but data binding across these platforms is relatively similar, so a lot of the concepts will carry across without me having to give multiple examples. Additionally, most of these concepts will apply equally well to data binding in Silverlight or WPF.

    There are a couple of questions that we need to address:

    - What is data binding?

    - Why do we need data binding?

    Let’s address the first question in this post by walking through an example. On our page we have two TextBlock elements that display the application title and the page name. These are illustrated with static placeholder text values (we’ll discuss design time data in a later post), which will be replaced with the actual values when the application is run.

    image 

    <StackPanel x:Name="TitlePanel">
        <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" />    
        <TextBlock x:Name="PageTitle" Text="page name" />
    </StackPanel>

    Without data binding in order to update the Text property on the TextBlock elements you would have see code like this:

    ApplicationTitle.Text = "DATA BINDING ROCKS!";
    PageTitle.Text = "simple data binding";

    Now, let’s do the same thing with data binding. Firstly, the XAML:

    <StackPanel x:Name="TitlePanel" >
        <TextBlock x:Name="ApplicationTitle" Text="{Binding}" />
        <TextBlock x:Name="PageTitle" Text="{Binding}" />
    </StackPanel>
     

    Next, the code:

    ApplicationTitle.DataContext = "DATA BINDING ROCKS!";
    PageTitle.DataContext = "simple data binding";

    If you look at the XAML instead of setting the Text property on the TextBlock elements to an explicit value, the attribute value is wrapped in { } – this essentially means that the value needs to be calculated some how (another typical usage of the { } value is for referencing a static resource). In this case the calculation is to create the data binding relationship between the Text property on the TextBlock and whatever is set as the current DataContext on the TextBlock. When we then set the DataContext on the TextBlock element it flows down into the Text property.

    image

    Where data binding starts to get more interesting is when you set the DataContext to be a more complex object. For example we might have a PageInfo class which contains the application title and page name:

    var pi = new PageInfo
        {
            ApplicationTitle = "DATA BINDING ROCKS!",
            PageTitle = "simple data binding"
        };
     
    ApplicationTitle.DataContext = pi;
    PageTitle.DataContext = pi;

    In this case we’re setting the DataContext on both TextBlock elements to be the PageInfo instance. When we run this what we see is that the data binding framework has literally just called “ToString()” on the object, which by default returns the type name as we can see in this image.

    image

    This isn’t what we want! What we want is that the first TextBlock should show the ApplicationTitle property and the second should show the PageTitle property. To do this we use the Path attribute on the data binding expression:

    <StackPanel x:Name="TitlePanel" >
        <TextBlock x:Name="ApplicationTitle"
                    Text="{Binding Path=ApplicationTitle}" />
        <TextBlock x:Name="PageTitle"
                    Text="{Binding PageTitle}" />
    </StackPanel>

    In the second TextBlock the  “Path=” has been omitted to illustrate the shorthand way to specify the Path attribute. In both cases the binding expression is setting up a data binding relationship between the Text property on the TextBlock with the ApplicationTitle (or PageTitle) property on the current DataContext, which in this case is an instance of the PageInfo class.

    An interesting aspect of the DataContext property on a UIElement is that by default it is inherited from its parent element. So for example in our scenario both TextBlock elements are situated within a StackPanel (ie the TitlePanel). By default (ie if the DataContext isn’t explicitly set on the TextBlock) they will both inherit the DataContext of the StackPanel. This means we could reduce our code to:

    var pi = new PageInfo
        {
            ApplicationTitle = "DATA BINDING ROCKS!",
            PageTitle = "simple data binding"
        };
     
    TitlePanel.DataContext = pi;

    (At this point we can also remove the x:Name attribute on both TextBlock elements as they are no longer required)

    Let’s just confirm our understanding of this:

    - The  “{Binding ApplicationTitle}” expression is shorthand for  “{Binding Path=ApplicationTitle}”

    - Text=“{Binding ApplicationTitle” sets up a binding relationship between the Text property on the TextBlock with the ApplicationTitle on the current DataContext

    - The DataContext of the TextBlock is inherited from its parent element, the TitlePanel StackPanel.

    - We’re explicitly setting the DataContext on the TitlePanel, allowing it to be inherited by the TextBlock elements.

    An alternative would be to set the DataContext on the entire page:

    var pi = new PageInfo
        {
            ApplicationTitle = "DATA BINDING ROCKS!",
            PageTitle = "simple data binding"
        };
     
    this.DataContext = pi;

     

    In this case our code is being executed in the context of the page, so the “this” is the page and so we’re setting the DataContext on the page and allowing it to flow down to every element on the page.

    The answer to the first question, “what is data binding?”, is that it’s about establishing an association between an attribute on a visual element with a data entity, or a property on a data entity. As we’ll see over the coming posts, data binding allows to separate the logic of our application from the way it is presented on the screen. This not only allows for cleaner and more manageable code, it also allows developers and designers to work independently on the same application.

    In the next post we’ll look at why you should be using data binding and the saving it offers to application developers.

    Some great SQLite for Windows Phone posts

    SQLite WinRT

    SQLite WinRT wrapper for Windows Phone

    http://sqlwinrt.codeplex.com/

    SQLite-WinRT: Database programming on Windows Phone and Windows 8

    A new SQLite wrapper for Windows Phone 8 and Windows 8 – The basics

    A new SQLite wrapper for Windows Phone 8 and Windows 8 – Relationships

     

    SQLite-net

    Working with SQLite in Windows Phone 8: a sqlite-net version for mobile

    How to use SQLite in Windows Phone

    Using the SQLite database engine with Windows Phone 8 apps

    ---- warning: self promption ----

    Windows (RT and Phone) and Sqlite (Part 1)
    Windows (RT and Phone) and Sqlite (Part 2)
    Windows (RT and Phone) and Sqlite (Part 3)
    Windows (RT and Phone) and Sqlite (Part 4)

    Windows Azure Mobile Service to SQLite Data Sync for Windows Phone and Windows RT with Portable Class Libraries

    Windows Azure Mobile Service to SQLite Data Sync for Windows Phone and Windows RT with Portable Class Libraries - Conflicts

    Windows (RT and Phone) and Sqlite (Part 4)

    This is the fourth (and final) part in a series on using Sqlite across both Windows RT and Windows Phone. To catch up I suggest you take a look at parts 1, 2 and 3:

    Windows (RT and Phone) and Sqlite (Part 1)

    Windows (RT and Phone) and Sqlite (Part 2)

    Windows (RT and Phone) and Sqlite (Part 3)

    Just to recap, here is my list of goals:

    - Blendable: My project has to be designable in Blend at all times!

    - Sqlite: I want to use sqlite to store relational data across both Win8 and WP applications

    - PCL: I want to be able to do all my data access from a portable class library

    - Objects Not SQL: I want to be able to read and write objects, rather than write sql statements

    In part 3 we got most of the way using sqlite-winrt by abstracting the platforms specific implementations into a set of interfaces which were exposed by a portable class library (PCL). This meant we could have all our application logic in a reusable class library (ie another PCL). We’re going to use a similar technique in this post to do the same thing with sqlite-net. This should solve the last remaining issue which was being able to query using objects, not sql.

    In part 2 we discussed briefly how to get started with sqlite-net. Essentially for Windows Phone you needed an additional native-to-managed bridge, in addition to referencing the SQLite for Windows Phone visual studio extension. When you add the sqlite-net from nuget you’ll have noticed that it added two files, SQLite.cs and SQLiteAsync.cs, which contain the LINQ style wrapper which makes it possible to read and write objects. It’s our goal to define a set of interfaces which can be extracted into a PCL.

    Interfaces

    As we did in the previous part with sqlite-winrt, the first step is to create a separate SQLitePCL project and to define a set of interfaces which map to the classes/methods which is exposed by Sqlite-net. I’m not going to bore you with the details but you can see from following image just a couple of the interfaces which will map to classes such as the SQliteConnection, TableMapping and Column.

    image

    Platform Implementations

    For each platform we need to implement these interfaces. This is really a matter of taking the sqlite-net classes, defined in SQLite.cs and SQliteAsync.cs and modifying them to implement the defined interfaces. This isn’t quite as simple as adjusting the class signature to include the appropriate interface but it isn’t far off.

    We need to create a separate class library for each platform, eg SQLiteWinRT and SQLiteWP8. It doesn’t matter which platform you start with (I did the phone implementation first) since you’ll be referencing the same classes using the “add as link” technique discussed in the previous post. You might be thinking, if we’re simply going to be adding the same classes to both libraries why they can’t be all in the shared PCL. The answer lies in the conditional compilation statements at the top of the sqlite-net files – these determine how the classes are built for the respective platforms.

    You’ll also need to add a class which will act as a connection factory:

    public class SQLiteConnectionFactory : ISQLiteConnectionFactory
    {
        public ISQLiteConnection Create(string address)
        {
            return new SQLiteConnection(address);
        }
    }


    Again, this class can be shared across both class libraries.

    Application PCL

    In the portable class library for your application you can now access Sqlite using a LINQ style interface (ie using objects, not sql). The only thing your PCL needs is a reference to an implementation of the ISQLiteConnectionFactory interface. In the following code for simplicity we’re doing this with a public property on the DataAccessClass but in a real application you might want to use a DI framework to inject this as required.

    public class DataAccessClass
    {
        public ISQLiteConnectionFactory Factory { get; set; }
        public void DoSomeStuff(string path)
        {
            using (var con = Factory.Create(path))
            {
                con.BeginTransaction();
                con.CreateTable<Person>();
                con.Insert(new Person { Name = "Nick", Age = 15 });
     
                var people = con.Table<Person>().ToArray();
                Debug.WriteLine(people.Length);
                con.Commit();
            }
        }
     
        public class Person
        {
            [PrimaryKey, AutoIncrement]
            public int Id { get; set; }
            public string Name { get; set; }
            public int Age { get; set; }
        }
    }

    Assigning a Platform Implementation

    The last thing you need to do, before you start accessing sqlite (eg calling the DoSomeStuff method) is to pass in the platform specific ISQLiteConnectionFactory implementation. As I mentioned you can do this using your favourite DI framework. In the following snippet I’m simply assigning it in the code behind of our sample application (not an ideal way to do it but super simple for demonstration of the concept!). The following code is from the MainPage.xaml.cs file in the Windows Phone application but the Windows RT code is exactly the same, just referencing the SQLiteWinRT namespace for the platform specific implementation.

     

    public static string DB_PATH = Path.Combine(Path.Combine
                       (ApplicationData.Current.LocalFolder.Path, "sample.sqlite"));
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
     
        var factory = new SQLiteConnectionFactory();
     
        var dac = new DataAccessClass();
        dac.Factory = factory;
     
        dac.DoSomeStuff(DB_PATH);
     
    }

     

    And there you have it…. accessing data using objects from within your PCL. So let’s do another recap of our goals:

    - Sqlite: Tick!

    - PCL: Tick!

    - Objects Not SQL: Tick!

    - Blendable: Tick! (assuming you installed the update I mentioned in part 3).

     

    I’ve included a sample project which includes all of the libraries and code discussed.

    Windows Phone 8 SDK - Deploying Multiple Enterprise Applications

    I’ve already talked about the basics of enterprise application deployment with Windows Phone 8, which you can find in the following two posts.

    Windows Phone 8 SDK- Enterprise Application Deployment

    Windows Phone 8 SDK- Enterprise Applications (part 2)

    In this post we’re going to look at how you can start to manage and deploy multiple enterprise applications. Of course, there will be some organisations who use an MDM provider (for example Silverback) which will facilitate the deployment of applications to specific groups of employees. However, there will be some organisations that elect not to use an MDM, and yet still want to deploy multiple enterprise applications. For this you can use some of the new APIs in Windows Phone 8 to enumerate installed applications and prompt for installation of applications.

    Let’s put this in a bit of context – a common starting point is to roll out a company hub style application. By this we mean a simple enterprise application (ie signed by the enterprise for internal distribution) which might list internal news, relevant links and a list of other enterprise applications that are available for installation. The company hub might also require the user to enter credentials in order to personalise these items (eg present only applications that the user should have access to)

    image

    If the user clicks on these applications there are a number of ways that the company hub can install the selected application. Assuming that the application is stored on a remote server you can simply launch the uri pointing to the xap file.

    private void InstallAppClick(object sender, RoutedEventArgs e)
    {
        var url = new Uri("http://mydomain.com/myapp.xap");
        Launcher.LaunchUriAsync(url);
    }

    Whilst this will work, assuming that the enterprise certificate that the application has been signed with is already installed on the device, it doesn’t provide a great experience for the user. Another alternative is to use the AddPackageAsync method on the InstallationManager.

    private async void InstallAppClick(object sender, RoutedEventArgs e)
    {
        var url = new Uri("http://mydomain.com/myapp.xap");
        var status = InstallationManager.AddPackageAsync("MyApp", url);
        status.Progress += UpdateProgress;
        await status;
    }
    private void UpdateProgress(IAsyncOperationWithProgress<PackageInstallResult, uint> asyncinfo, uint progressinfo)
    {
        // Update UI with progress
    }

    The return value from the AddPackageAsync method can be used to retrieve installation progress information that can be displayed within the company hub whilst the application is being installed.

    Both these alternatives download the xap in clear form from the remote server. Whilst this might be ok if the user is on an intranet, it’s not a great solution if you want to make applications accessible to remote users (which you would hope would be the case since they’re mobile….). In this case you really need to ensure the application is encrypted or protected somehow to prevent the applications from being decompiled. The script for signing the applications does not provide any level of protection – it simply invokes a native compile of the dlls and then signs both dlls and xap. As such you should consider applying your own level of protection, which in turn means we need an alternative method to install the applications via the company hub.

    One solution is to package the other applications into the company hub. Each application needs to be created and then signed using the enterprise certificate. They’re then added to the company hub project with the build action property set to Content – this ensures they’re packaged with the company hub. Once the company hub has been installed the user can select one of the applications packaged with the company hub for installation. Since the application isn’t downloaded there is no way to intercept it, so no further protection is required. This method again uses the AddPackageAsync but this time with a uri that points to a file packaged with the company hub (progress reporting has been omitted for brevity). Alternatively you can also use the Launcher.LaunchFileAsync with a reference to the file but again this doesn’t report on the installation progress.

    private async void InstallAppClick(object sender, RoutedEventArgs e)
    {
        var file = await StorageFile.GetFileFromApplicationUriAsync(new System.Uri("ms-appx:///myapp.xap"));
        var fullSystemPath = new Uri("file://" + file.Path);
        await InstallationManager.AddPackageAsync("MyApp", fullSystemPath);
    }

    One thing to note here is the slightly unusual path syntax that is required by the AddPackageAsync method. It will not work with either a relative uri or a uri starting with ms-appx or ms-appdata.

    The downside of this method is that you need to bundle all the other applications into the company hub, even if they’re not relevant to the current user. A better solution is to download an encrypted application from a remote server, decrypt it locally, and then install the application from isolated storage. In this post we won’t cover the first two steps, as this is up to the organisation as to how they wish to encrypt the application file and distribute the keys to the company hub application so it can decrypt the application file. The last step is actually similar to installing an application that is packaged with the company hub. However, this time the file is stored in isolated storage, which slightly changes the way the file path is constructed (you could also use new Uri(“ms-appdata://local/MyApp.xap”) rather than using the LocalFolder).

    private async void InstallAppClick(object sender, RoutedEventArgs e)
    {
        var storageFolder = ApplicationData.Current.LocalFolder;
        var file = await storageFolder.GetFileAsync("MyApp.xap");
        var fullSystemPath = new Uri("file://" + file.Path);
        await InstallationManager.AddPackageAsync("MyApp", fullSystemPath);
    }

    In this post you’ve seen how you can install additional enterprise applications from a company hub. In deciding which method to use you should consider both the sensitivity of the application logic and the risk of data being intercepted.

    DNS Client for Windows and Windows Phone

    Don’t ask why, but I needed to be able to do a dns record lookup for a srv record from a Windows Phone application. I went looking for a library that could do this and came up with Phone Net Tools (http://phonenettools.codeplex.com/) – this seems a great library but fairly rudimentary support for DNS queries. I also came across a great post by Rob Philpott on CodeProject (http://www.codeproject.com/Articles/12072/C-NET-DNS-query-component) – it’s a bit dated and for legacy technologies (I needed to upgrade everything to even run it!). Whilst this option seemed to be more painful to update the architecture seemed to lead itself to being extended to support srv records. The net effect is there is yet another library on codeplex, this one dedicated to doing DNS lookups from a Windows 8 or Windows Phone application.

    At the moment I’ve only got the Windows Phone version uploaded to the Windows and Windows Phone DNS Library. It’s relatively simple to use:

    // create a DNS request
    var request = new Request();

    var domain = "builttoroam.com";
    var type = DnsType.MX;
    var dnsServer = IPAddress.Parse("203.0.178.191");

    // create a question for this domain and DNS CLASS
    request.AddQuestion(new Question(domain, type, DnsClass.IN));

    // send it to the DNS server and get the response
    //Response response =

    var resp = await Resolver.Lookup(request, dnsServer);
    foreach (var answer in resp.Answers)
    {
        Debug.WriteLine("{0}", answer.Record);   
    }