Nick's .NET Travels

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

A Simple ViewModelLocator for Spawning ViewModels for XAML Based Applications

There are numerous frameworks out there that provide mechanisms for instantiating view models. Long again, when I first started building XAML based applications and became familiar with MVVM, I stepped through a number of different ways of creating and wiring up view models. In this post I’m going to show a very basic implementation of a locator to instantiate view models. Into the Core library I will add a ViewModelLocator class which exposes a property, Main, that will return a new instance of the MainViewModel.

public class ViewModelLocator
{
    public MainViewModel Main
    {
        get { return CreateViewModel<MainViewModel>(); }
    }

    private T CreateViewModel<T>() where T:new()
    {
        return new T();
    }
}

I’m going to want a single instance of this class to be created and kept around for the duration of my application’s lifecycle. One option would be to instantiate it within my ApplicationCore class I introduced previously. However, I actually want the instance of the ViewModelLocator to be accessible via XAML, so for this reason it makes more sense to instantiate it as a XAML resource. In the WPF and Universal (Win/WP8.1) applications I can simply add this to the app.xaml file to the Application.Resource element.

<Application.Resources>
        <core:ViewModelLocator x:Key="Locator" />
</Application.Resources>

In the MainWindow (WPF) and MainPage (Universal) I can now specify the DataContext in the opening element, removing the need to create the MainViewModel in code in the codebehind file. Eg

<Window x:Class="RealEstateInspector.Desktop.MainWindow"
        xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        DataContext="{Binding Main, Source={StaticResource Locator}}" >

The current implementation of Xamarin.Forms doesn’t seem to support creating Application resources in XAML. However, by tweaking the App constructor, I can add an instance of the ViewModelLocator:

public App()
{
    Resources = new ResourceDictionary();
    Resources.Add("Locator", new ViewModelLocator());

    MainPage =new MainPage();
}

The syntax in the MainPage of the XForms application is similar except BindingContext replaces DataContext:

BindingContext="{Binding Main, Source={StaticResource Locator}}"

There seems to be a quirk in XForms at the moment in that the Binding expression calls to the Main property repeatedly – since it gets a different instance of the MainViewModel back each time, it ends up in an endless loop trying to get a consistent value. To prevent this, we can add a view model dictionary to the ViewModelLocator and change the behaviour to always return the same instance of the view model.

private readonly Dictionary<Type, object> viewModels = new Dictionary<Type, object>();

private T CreateViewModel<T>() where T:new()
{
    var type = typeof (T);
    object existing;
    if (!viewModels.TryGetValue(type, out existing))
    {
        existing = new T();
        viewModels[type] = existing;
    }
    return (T)existing;
}

And there you have it – view model location across all applications.

Adding Azure Active Directory Authentication to Windows Phone 8.0 Application with Xamarin.Forms

In the previous post I covered addition authentication to the Windows platform applications but I explicitly excluded the Windows Phone 8.0 project that’s part of the XForms set of projects. This was because the ADAL doesn’t currently support Windows Phone 8.0. In this post we’ll add a custom implementation which will authenticate the user using a WebBrowser control within the Windows Phone 8.0 application. We’ll start by adding a reference to the Windows Phone 8.0 project to the Shared.Client project – this will cause build errors as there is no reference to ADAL so the classes which are referenced in this shared code don’t exist. I’ll make some small amendments using the SILVERLIGHT compilation attribute (note that this is only defined for the WP8.0 project):

using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
#if !SILVERLIGHT
using Microsoft.IdentityModel.Clients.ActiveDirectory;
#else
using RealEstateInspector.XForms.WinPhone;
#endif
using RealEstateInspector.Core;

namespace RealEstateInspector.Shared.Client
{
    public static class AuthenticationHelper
    {

        public static async Task<string> Authenticate()
        {
            try
            {
                var authContext = new AuthenticationContext(Constants.ADAuthority);
#if !SILVERLIGHT
                if (authContext.TokenCache.ReadItems().Count() > 0)
                    authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().First().Authority);
#endif

                var authResult =
                    await
                        authContext.AcquireTokenAsync(Constants.MobileServiceAppIdUri,
                        Constants.ADNativeClientApplicationClientId,
                        new Uri(Constants.ADRedirectUri),
#if WINDOWS_PHONE_APP || SILVERLIGHT
                        new AuthorizationParameters()
#else
                            new AuthorizationParameters(PromptBehavior.Auto, false)
#endif
                        );
                Debug.WriteLine(authResult != null);

                return authResult.AccessToken;

            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                return null;
            }
        }
    }
}

The next thing to do is to provide an implementation of the AuthenticationContext class and it’s associated classes. These are added to the Windows Phone 8.0 project:

public class AuthenticationResult
{
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }
}

public class AuthorizationParameters
{
}

public class AuthenticationContext
{
    public string Authority { get; set; }
    public string Resource { get; set; }
    public string ClientId { get; set; }
    public Uri RedirectUri { get; set; }

    public AuthenticationContext(string authority)
    {
        Authority = authority;
    }

    public async Task<AuthenticationResult> AcquireTokenAsync(
        string resource,
        string clientId,
        Uri redirectUri,
        AuthorizationParameters parameters)
    {
        Resource = resource;
        ClientId = clientId;
        RedirectUri = redirectUri;
        var code = await Authenticate();

        var http = new HttpClient();

        var tokenUrl = string.Format("{0}/oauth2/token",Authority);
        var formData = new Dictionary<string, string>
        {
            {"grant_type","authorization_code"},
            {"client_id",ClientId},
            {"code",code},
            {"resource",Resource},
            {"redirect_uri",RedirectUri.OriginalString}
        };

        var content = new FormUrlEncodedContent(formData);
        var data = await http.PostAsync(new Uri(tokenUrl), content);
        var result = JsonConvert.DeserializeObject<AuthenticationResult>(await data.Content.ReadAsStringAsync());
        return result;
    }

    private ManualResetEvent authenticateWaiter = new ManualResetEvent(false);
    private string AccessToken { get; set; }
    public async Task<string> Authenticate()
    {
        authenticateWaiter.Reset();
        var authUrlTemplate =
            "{0}/oauth2/authorize?response_type=code&client_id={1}&redirect_uri={2}";
        var authUrl = string.Format(authUrlTemplate,
            Authority,
            ClientId,
            Uri.EscapeDataString(RedirectUri.OriginalString)
            );

        var page = (Application.Current.RootVisual as Frame).Content as Page;
        var firstChild = page.Content;
        if (!(firstChild is Grid))
        {
            page.Content = null;
            var gd = new Grid();
            gd.Children.Add(firstChild);
            page.Content = gd;
            firstChild = gd;
        }

        var mainGrid = firstChild as Grid;
        var browser = new WebBrowser
        {
            IsScriptEnabled = true
        };
        browser.Navigating += BrowserNavigating;
        Grid.SetRowSpan(browser, (mainGrid.RowDefinitions != null && mainGrid.RowDefinitions.Count > 0) ? mainGrid.RowDefinitions.Count : 1);
        Grid.SetColumnSpan(browser, (mainGrid.ColumnDefinitions != null && mainGrid.ColumnDefinitions.Count > 0) ? mainGrid.ColumnDefinitions.Count : 1);
        mainGrid.Children.Add(browser);
        browser.Navigate(new Uri(authUrl));

        await Task.Run(() => authenticateWaiter.WaitOne());
        return AccessToken;
    }

    private void BrowserNavigating(object sender, NavigatingEventArgs e)
    {
        if (e.Uri.OriginalString.ToLower().StartsWith(RedirectUri.OriginalString.ToLower()))
        {
            try
            {
                var query = e.Uri.OriginalString.Substring(e.Uri.OriginalString.IndexOf('?') + 1);
                var code = (from pair in query.Split('&')
                            let bits = pair.Split('=')
                            where bits.Length == 2
                                    && bits[0] == "code"
                            select bits[1]).FirstOrDefault();
                AccessToken = code;
            }
            catch (Exception ex)
            {
                AccessToken = null;
            }
            finally
            {
                authenticateWaiter.Set();
                var browser = sender as WebBrowser;
                browser.Navigating -= BrowserNavigating;
                (browser.Parent as Grid).Children.Remove(browser);
            }
        }
    }
}

Reading this code you’ll see that I’m manually inserting and removing a WebBrowser control into the current page of the WP8.0 application. This is then used to authenticate the user and return the

authorization code which is then used to make the POST to request the access token (basically following what I did in my previous post when I walked this through manually in the browser/Fiddler).

I’ve also updated the XAML in my XForms MainPage:

<Page
    x:Class="RealEstateInspector.MainPage"
    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">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.Resources>
            <DataTemplate
                x:Key="PropertyItemTemplate">
                <TextBlock
                    Text="{Binding Address}"
                    FontSize="30"
                    Foreground="WhiteSmoke"/>
            </DataTemplate>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition />
        </Grid.RowDefinitions>
        <Button Content="Authenticate" Click="AuthenticateClick"/>
        <ListView
            ItemTemplate="{StaticResource PropertyItemTemplate}"
            Grid.Row="1"
            ItemsSource="{Binding Properties}"/>
    </Grid>
</Page>

As well as the code behind to handle the button click:

public static event EventHandler AuthenticateRequested;

public void AuthenticateClick(object sender, EventArgs e)
{
    if (AuthenticateRequested != null)
    {
        AuthenticateRequested(this, EventArgs.Empty);
    }
}

Lastly in the MainPage of my Windows Phone 8.0 application I’ve wired up a listener for the AuthenticateRequested event to make sure I can trigger the authentication process:

public MainPage()
{
    InitializeComponent();
    SupportedOrientations = SupportedPageOrientation.PortraitOrLandscape;

    global::Xamarin.Forms.Forms.Init();
    RealEstateInspector.XForms.MainPage.AuthenticateRequested += Authenticate;
    LoadApplication(new RealEstateInspector.XForms.App());
}

public async void Authenticate(object sender, EventArgs e)
{
    var page = sender as RealEstateInspector.XForms.MainPage;
    var token = await AuthenticationHelper.Authenticate();
    Debug.WriteLine(token);
    (page.BindingContext as MainViewModel).LoadPropertyData(token);
}

Authenticating With Azure Active Directory In Universal Windows Platform Applications

The AAD team are continuing to evolve the samples and NuGet packages that can be referenced when authenticating with Azure Active Directory. In this post I’m going to add authentication to the Windows platform applications using the Active Directory Authentication Library (package id: Microsoft.Indentity.Clients.ActiveDirectory) and the corresponding sample found on github (https://github.com/AzureADSamples/NativeClient-MultiTarget-DotNet). One limitation of the current ADAL is that it doesn’t support Windows Phone 8.0 – adding support for this platform is slightly harder than for universal applications as there is no WebAuthenticationBroker so doing authentication will have to be done via a hosted web browser control within the application.

The first step in adding authentication support across the applications is to a reference to the ADAL package. I’ve added it to the Windows and Windows Phone 8.1 projects, as well as the iOS and Android XForms applications. As the package doesn’t support WP8.0 it can’t be added to either the XForms portable class library, the Core portable class library, nor the Windows Phone 8.0 projects. At this stage we’ll exclude the Mobile Service project as we currently don’t need ADAL there.

Into the RealEstateInspector.Core portable class library I’m going to add a Constants class which contains the various values required when requesting the authorization code and access token using the ADAL.

public static class Constants
{
    public const string ADTenant = "realestateinspector.onmicrosoft.com";
    public const string ADAuthority="https://login.windows.net/" + ADTenant;

    public const string ADNativeClientApplicationClientId = "a5a10ee9-f871-4bde-997f-3f1c323fefa5";

    public const string ADRedirectUri = "http://tba.com";

    public const string MobileServiceAppIdUri= "https://realestateinspector.azure-mobile.net/login/aad";
}

Rather than having to duplicate the authentication code between each of the client projects I’m going to create another Shared project called RealEstateInspector.Shared.Client and add a class called AuthenticationHelper. I’ll add a reference to this project to all of the client projects, except the Windows Phone 8.0 project, since this is currently unsupported.

public static class AuthenticationHelper
{

    public static async Task<string> Authenticate()
    {
        try
        {
            var authContext = new AuthenticationContext(Constants.ADAuthority);
            if (authContext.TokenCache.ReadItems().Count() > 0)
                authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().First().Authority);
            var authResult =
                await
                    authContext.AcquireTokenAsync(Constants.MobileServiceAppIdUri,
                    Constants.ADNativeClientApplicationClientId,
                    new Uri(Constants.ADRedirectUri),
#if WINDOWS_PHONE_APP
                    new AuthorizationParameters()
#else
                        new AuthorizationParameters(PromptBehavior.Auto, false)
#endif
                    );
            Debug.WriteLine(authResult != null);

            return authResult.AccessToken;

        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
            return null;
        }
    }
}

In our Windows platform projects I need to update the AuthenticationClick methods as follows:

private async void AuthenticateClick(object sender, RoutedEventArgs e)
{
    var token = await AuthenticationHelper.Authenticate();
    await CurrentViewModel.LoadPropertyData(token);

}

And I’ve made a simple tweak to the LoadPropertyData method to accept the access token as a parameter.

The last thing to do is in the App.xaml.cs file to add an override to the OnActivated method. Note that this is required due to the differences in the WebAuthenticationBroker implementations between Windows and Windows Phone 8.1.

protected override void OnActivated(IActivatedEventArgs args)
{
    base.OnActivated(args);

#if WINDOWS_PHONE_APP
    if (args is IWebAuthenticationBrokerContinuationEventArgs)
    {
        WebAuthenticationBrokerContinuationHelper.SetWebAuthenticationBrokerContinuationEventArgs(args as IWebAuthenticationBrokerContinuationEventArgs);
    }
#endif

}

At this point whilst we’ve added references to ADAL to the client projects, the only applications that can be run and signed into are the Windows platform applications (Windows and Windows Phone 8.1).

Building the Xamarin.Forms Basic Layout Using XAML

The initial content page that was created when we created the XForms projects was done in code. Rather than doing the layout in code, I prefer to work in XAML – not only does this make the design more declarative, it is also miles easier to data binding. I’ll start by creating a new Forms Xaml Page.

image

Next we’ll add some XAML to the page (similar to what we added to the Windows MainPage):

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="
http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="RealEstateInspector.XForms.MainPage">
  <ListView ItemsSource="{Binding Properties}">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell>
          <ViewCell.View>
            <Label Text="{Binding Address}" />
          </ViewCell.View>
        </ViewCell>
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>
</ContentPage>

And in the code behind for the MainPAge we’ll create, assign and load data into the MainViewModel:

protected async override void OnAppearing()
{
    base.OnAppearing();

    var vm = new MainViewModel();
    BindingContext = vm;
    await vm.LoadPropertyData();
}

And of course I need to update the code in App.cs to use the new XAML MainPage, rather than the code created ContentPage:

public App()
{
    // The root page of your application
    MainPage =new MainPage();
}

When you go to run this you’re likely to see errors due to lack of references for the SQLite extensions. Most references will get added if they are used by referenced libraries. What makes SQLite different is that there are platform specific implementations which are only added to the platform specific project. As such you need to make sure all the client applications have the SQLiteStore NuGet package referenced. I ran into issues applying the NuGet package to the Android project as it seemed to not be able to find the HttpClient NuGet package – I had to add this NuGet package to the Android project first, before applying the SqliteStore NuGet Package.

image

After doing this I was able to run up the XForms applications on each of the platforms, each displaying the addresses of the properties in my local offline database.

Adding Xamarin.Forms Support

So far I’ve only had support for the new Windows platform clients (ie Windows and Windows Phone) for my Real Estate Inspector sample app. However, to make it successful we need to target more platforms. To this end I’m going to add support for iOS, Android and Windows Phone 8.0 using Xamarin.Forms.

After installing the Xamarin tooling for Visual Studio, I added a new project using the Blank App (Xamrain.Forms Portable) template. This actually look multiple attempts as I hadn’t updated the Xamarin tooling prior to creating the projects. I would highly recommend upgrading the tooling first!

image

This will give you three target projects Driod, iOS and WinPhone, in addition to a PCL which contains the common code and ui for the applications. You should be able to build and run each of these targets – however, you’ll need to either register for a trial or have a Xamarin Business subscription. Since the UI is help in the PCL project, it’ll be the same across all the targets, although there may be platform rendering differences.

Now that we have these three targets, we’re going to have to connect up our Azure Mobile Service, work out how we’re going to deal with navigation and structure our solution to maximise code reuse across our Windows platform projects.

Synchronizing Data for Offline Access with Azure Mobile Service

One of the core requirements of our real estate inspection tool is that it’s available offline. To this end I can leverage the synchronisation component of the Azure Mobile Service SDK to synchronise the entities we referenced in the previous post. In order to make use of this I will need to add another NuGet package which is the WindowsAzure.MobileService.SqliteStore package – you can think of this as the Sqlite storage wrapper which will handle persisting and providing an access layer to the offline data.

image

One thing you may notice that that there is a warning in your References list after adding this NuGet package. In this case you either haven’t got the Windows/Windows Phone Sqlite Extensions installed, or your version doesn’t align with the reference that was added as part of adding the previous package. After making sure you have the most recent version of the Sqlite extensions installed (get them from the Sqlite Download Page), you can then simply delete the reference with the warning, and then add a new reference to the extensions you just installed.

image

Next, you’ll probably still see warnings against the Sqlite and Visual C++ references – this is because neither of these references supports compiling using the AnyCPU option. Switch to building for one of the other platforms (x86 is probably the easiest to use for development since it’s compatible with the Windows Phone emulator, just don’t forget that if you’re testing  on an RT device or on a real Windows Phone, you’ll need to use an ARM build).

image

Now we have our references, let’s add some code to demonstrate synchronising, reading and writing from the offline data store. I already have my MobileService that I setup in a previous post but I’m going to replace my the method call to GetTable<>.ToListAsync() with code that will synchronise data for offline access. I’ll start by defining the offline data file, inspections.db, along with the entity tables that I want to include in the database. I then initialize the SyncContext of the MobileService using this data store

var data = new MobileServiceSQLiteStore("inspections.db");
data.DefineTable<RealEstateProperty>();
data.DefineTable<Inspection>();

await MobileService.SyncContext.InitializeAsync(data, new MobileServiceSyncHandler());

Invoking a sync is actually a two part process. First you need to pull data down from the Mobile Service. Here we’re passing in a default table query (which will pull down all entities in the table), and using the name of the data type as the synchronisation key. I repeat this for both entity types I want to synchronize.

var propertyQ = MobileService.GetSyncTable<RealEstateProperty>().CreateQuery();
await MobileService.GetSyncTable<RealEstateProperty>().PullAsync(typeof(RealEstateProperty).Name, propertyQ);

var inspectionQ = MobileService.GetSyncTable<Inspection>().CreateQuery();
await MobileService.GetSyncTable<Inspection>().PullAsync(typeof(Inspection).Name, inspectionQ);

You’ll notice that I’m calling GetSyncTable instead of GetTable – this is because I want to reference the local offline table, rather than the Mobile Service endpoint. Now that I’ve pulled data down from the Mobile Service I can call ToListAsync on the sync table to retrieve all the elements that are contained in the offline table.

var props = await MobileService.GetSyncTable<RealEstateProperty>().ToListAsync();

Inserting items is a simple as creating them and inserting them into the sync table

var inspection = new Inspection
{
    InspectedBy = "Joe",
    RealEstatePropertyId = props[0].Id
};
await MobileService.GetSyncTable<Inspection>().InsertAsync(inspection);

Of course this only adds them to the local offline table. To push them up to the Mobile Service I call PushAsync on the synchronization context.
await MobileService.SyncContext.PushAsync();

Lastly to validate that the new items have appeared in the Mobile Service I can query it directly to get all items in the Mobile Service table

var inspections = await MobileService.GetTable<Inspection>().ToListAsync();

If you’re interested in what’s stored in the offline data file it can be found at C:\Users\<username>\AppData\Local\Packages\<package id>\LocalState and you can use a tool like SqliteStudio to view the contents of the database file

image

And you can use the SQL query window to write and execute sql to view the data.

image

Updating the Windows and Windows Phone Applications with the new Azure Mobile Service Entities

In my previous post I extended the Azure Mobile Service to include two entities, RealEstateProperty and Inspection. I’m now going to return to the Windows platform projects (ie Windows and Windows Phone) and update them to use these new entities.Rather than duplicate the entity definition I’m going to reuse the entity definition I created previously. Unfortunately, the base class of the two entities is a class called EntityData which is specific to Azure Mobile Service SDK for the full .NET Framework (ie to power the .NET backend services). This means we can simply move these entities into a class library, or better still a PCL, and reference it. Instead we’ll need to make the base class conditional on where the entities are being used – this is a great use for a Shared Project.

We already have a Shared Project which is used to share common code between the Windows platform projects. One option would be to simply reference this project from the service project but this would mean we couldn’t include any shared XAML or Windows platform specific code. Instead I’m going to create a new Shared Project which will be used to contain the entities that are going to be shared across both the Windows platform projects and the service project. To do this I need to download and install the Shared Project Reference Manager which extends Visual Studio to allow for the easy creation and referencing of Shared Projects. After installing the extension I simply add a new project as I would any other project type – right-click the solution node in Solution Explorer and select Add –> New Project. Select the Shared Project and give it a name, in this case will keep it inline with the other Shared Project by naming it RealEstateInspector.Shared.Entities.

image

With the Shared Project created, I need to add a reference to the Shared Project to both Windows platform projects and the service project – right-click the References node under the project and select Add Shared Project Reference. The two Windows platform projects should have both shared projects selected, whilst the service project should only reference the new Shared Project.

image

Next I need to move my entities out of the service project and into the shared project. I’ll also take this opportunity to change the base class, which as you’ll see will allow us to provide a different base class implementation depending on whether the entities are being compiled into the windows platform projects or the service project.

public class RealEstateProperty : BaseEntityData
{
    public string Address { get; set; }

    public virtual ICollection<Inspection> Inspections { get; set; }
}

public class Inspection : BaseEntityData
{
    public string InspectedBy { get; set; }

    public string RealEstatePropertyId { get; set; }
    public RealEstateProperty RealEstateProperty { get; set; }

}

The BaseEntityData class looks like this:

#if SERVICE
using Microsoft.WindowsAzure.Mobile.Service;
#endif

namespace RealEstateInspector.Shared.Entities
{
    public class BaseEntityData
#if SERVICE
       : EntityData{}
#else
    {
        public string Id { get; set; }
    }
#endif
}

You’ll notice that the BaseEntityData makes use of a compilation symbol to firstly control the base class (ie use the EntityData class if SERVICE is defined) and secondly whether the Id property is defined. The SERVICE symbol isn’t a predefined symbol so I’ll need to define that in my service project. I could have switched the logic to use one of the existing symbols, such as WINDOWS_APP but then if we ever extend this to other platforms, I’d have to modify the logic. It seems better to simply add a SERVICE symbol to the service project. Double-click the Properties node under the service project in Solution Explorer and then open the Build tab. Make sure you select All Configurations before adding SERVICE to the compilation symbols.

image

If I now go to the MainPage.Shared.cs (which I created in an earlier post) where we wrote the initial logic to query the TodoItems from the Mobile Service, I can update the code to instead use either, or both, the new entities we’ve defined:

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

    var items = await MobileService.GetTable<Inspection>().ToListAsync();
    Debug.WriteLine(items!=null);
}

Whilst I’ve refactored the service code, there’s no reason to publish the new version since we haven’t modified the structure of the entities. However, there should be no harm in doing so if you’d like to keep the service up to date.

Connecting Windows/Windows Phone Apps to Azure Mobile Service

In my previous post I created Windows and Windows Phone applications using the universal app template, and created and published a Mobile Service, The next step is to connect the apps to the Mobile Service using the Windows Azure Mobile Service NuGet package. In my solution I simply right-click on the solution node and select manage NuGet Packages. Locate the NuGet package by searching for “azure mobile service” and click Install next to the SDK package. Add the SDK to both Windows and Windows Phone projects but not the Service project.

image

Add a new file to the Shared project, MainPage.shared.cs and replace the MainPage class definition with the following:

public partial class MainPage
{
    public static MobileServiceClient MobileService = new MobileServiceClient(
            "
https://realestateinspector.azure-mobile.net/",
            "wpxaIplpe---------------------lZAPYQEBcg12"
    );

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

        var items = await MobileService.GetTable<TodoItem>().ToListAsync();
        Debug.WriteLine(items!=null);
    }
}

public class TodoItem
{
    public string Id { get; set; }
    public string Text { get; set; }
    public bool Complete { get; set; }
}

I can run either the Windows or Windows Phone application and see that the items variable gets populated with the contents of the TodoItems table. Of course we need to switch out this table with one that is more applicable to the property inspector application I’m building but this demonstrates how easily you can retrieve data using the Azure Mobile Service SDK.

Creating Your Solution and Your Azure Mobile Service

As I discussed in my initial post there are a number of components that make up the property inspection tool. In this post we’ll start by creating the initial solution structure, create and add in the Azure Mobile Service, and publish the Azure Mobile Service.

Initial Solution Structure

A lot of blog posts will start by creating the Azure Mobile Service and then use the template projects provided on the home page of the newly created Mobile Service. Sometimes this isn’t an option and you want to be able to integrate a Mobile Service into an existing application. For this reason I’m going to start with a new project creating Visual Studio using the Blank App Universal template.

image

This will create Windows and Windows Phone projects, with a Shared code project to handle files shared between the two applications.

image 

 

Creating the Azure Mobile Service

The next step is to create the Azure Mobile Service. This can actually be done by right-clicking on the Mobile Services node in the Server Explorer window in Visual Studio but I’m going to have to go to the management portal to download the initial project for the Mobile Service anyhow. To create the Azure Mobile Service, navigate to the Azure Management Portal and select New >> Compute > Mobile Service > Create from the toolbar at the bottom of the screen. Complete the setup wizard – make sure you select the .NET backend.

image

After completing the setup wizard, a few moments later the new Mobile Service will be available. However, before I can use it I need to publish the set of services -  you can think of what I’ve done so far as just setting up a placeholder for where the services will live.

Publishing the Mobile Service

To publish the Mobile Service I expand out the Get Started section on the home page of my newly created Mobile Service, and click on the Download link. I save the downloaded zip file, unblock and then extract the zip file.

image

I then copy the service folder (in my case realestateinspectorservice) into the solution folder of the solution I created earlier. Back in Visual Studio I then add the existing realestateinspectorservice project into the solution.

image

Right-click on the services project and select Publish. Select Microsoft Azure Mobile Services as the publish target

image

At this point if you’re not already signed in, you’ll need to sign into you Azure subscription with your Microsoft Account in order to select the previously created Mobile Service:

image

After selecting the Mobile Service to publish to, click OK and then the Publish button. This will cause the project to be compiled (and any required NuGet packages to be downloaded) and then published up to the Mobile Service. This may take a few minutes the first time as all referenced libraries will have to be copied up. However, future publish operations will be significantly quicker as they are by default differential.

After publishing the Mobile Service I can test that it’s operational using Fiddler (or curl etc) to simulate a GET request. I need two pieces of information: firstly the url of the Mobile Service I created. This can be found either in the Output window of Visual Studio at the end of publishing the Mobile Service, or from the dashboard pane of the Mobile Service in the Azure portal. The second thing is that I need one of the two assigned access keys. This again comes from the Azure management portal by clicking on the Manage Access Keys button in the toolbar at the bottom of the page. This key needs to be added to the request as the X-ZUMO-APPLICATION header. The following images show the request and response samples

 

image

image

 

So this gets me part of the way through setting up my solution – the next thing to do is to connect the Windows and Windows Phone applications so that they can call out to the Mobile Service…..

Mobile First, Cloud First and How it Applies to Line of Business Software

I’m going to start the year by dissecting a typical business scenario which will demonstrate how the use of Windows, Windows Phone and Azure can be plugged together to quickly deliver a line of business solution. Throw in a bit of Xamarin and a web front end and you have a solution that will enable employees to use any device they choose in order to access the software.

The first thing to cover is the scenario, which in this case is going to be a property inspection tool that could be used by a property manager to do periodic property inspections required under most rental agreements. At first glance this appears to be a tool that is specific for the real estate industry but as we’ll see there are a number of components that make it similar to any task, defect or issue tracking system:

- Property managers will have a number of properties assigned to them to manage
- Properties will have a history of inspections which may include images and/or videos
- Property information, and perhaps most recent inspection, needs to be available offline (just in case there is no internet inside a property being inspected)

- Inspections need to be able to be created, edited and submitted from a mobile device

This will probably do for the time being; as we go we may introduce other elements to demonstrate the use of various platform components. What’s interesting to note at this point is that properties can be switched out for projects, and inspections for tasks, if this scenario were a task/issue/defect tracking system.

At a high level let’s discuss the major components:

- Mobile devices – Naturally as .NET developers we gravitate to what’s easiest so we’ll include Windows and Windows Phone applications based on the universal app template which uses a shared code project to prompt reuse. However, we shouldn’t neglect the other platforms so we should include iOS and Android projects, using the Xamarin tooling. Our business logic we’ll abstract into a portable class library (PCL) to attempt to give us maximum reuse.

- Services – Azure Mobile Services will give us the raw scaffolding to stand up a SQL Server backend with services exposed to surface data to our mobile applications. These services support synchronisation which we’ll use to give the mobile applications offline support.

- Blobs – Azure Blob Storage will be used to store the images and videos collected as part of the solution. Whilst the service tier will be used to control access to Blog Storage (by issuing Shard Access Signatures) the upload will be done from the mobile applications directly into blob storage

- Authentication – As this is a line of business solution we’d prefer users to not have to remember another set of credentials. To this end the solution will use Azure Active Directory (AAD) to authenticate users and grant them access to the software. The users can be synchronised from the corporate AD into AAD so as to maintain a single set of credentials for any user.

- Web application – An Azure Website will be used to provide desktop and mobile solution for those unable to use the mobile applications. Whilst this could go directly to the SQL Server backend, it will in fact be routed via the service tier to ensure a common authentication pattern and usage model for the data.

- Scheduling – A scheduler will be setup in Azure for use by the solution in order to schedule particular jobs or operations to be carried out. For example the periodic generation and sending of reports.

- Push Notifications – When new data is available, push notifications can be sent out to the mobile applications to either alert the appropriate user, or perform a background synchronisation of the new data.

I’ll use this post as a reference for the components that I’ll be discussing in the coming posts. The components aren’t in any particular order and the posts won’t focus on individual components, rather how they connect together and what you need to know to get them to work together.

TechEd Australia – Sydney and Melbourne 2014

TechEd1

This year I’m delivering two sessions in both Melbourne (7-8th October) and Sydney (27-28th October):

Using Visual Studio and Blend to build Beautiful Universal Applications (WPD307)
The new Universal Application project promises to reduce the amount of code you need to write, but does it reduce the amount of design work you have to do? In this demo-heavy session, XAML guru Nick Randolph explores the tooling available in Blend and the patterns you’d use to produce stunning Universal Applications with a minimum amount of work.

Building and Migrating Modern Enterprise Line of Business Applications (WPD304)
Mostly, when we build enterprise applications, we’re not starting from scratch. Deciding what to build, what to reuse and what to keep is an important part of the enterprise software development decision process. In this session, Nick will explore the conditions and requirements that might lead you to decide which of these approaches to take. He’ll also demonstrate some techniques for taking an existing Line of Business application and lighting it up with a modern, touch-friendly UI.

 

If you’re attending in either session, come along and chat about the direction of the Windows platform and how to take advantage of it in your business.

Errors Installing and Running Windows Phone 8.1 Appx

Last week we ran into a couple of issues installing and running a Windows Phone 8.1 Appx application. Here are some of the symptoms:

  • Application deploys and runs fine in the emulator
  • Application deploys and runs fine on some phones running Windows Phone 8.1 but refused to install on other phones. The error given by Visual Studio when attempting to install the application was a rather cryptic, and overly useless, error code
  • Application package could be successfully signed using the signing tool as part of the SDK
  • Signed application package refuses to install on some retail phones running Windows Phone 8.1

It turns out that we were referencing the Active Directory Authentication Library which in turn was making a native call that only showed up when we ran the WACK test. As we weren’t planning to deploy via the Windows Store we hadn’t run the WACK test recently and it was only by chance that I ran it to see if it threw up any errors. Fixing the errors and warnings not only addressed the installation issue it also highlighted some issues with the project structure (incorrect images sizes etc).

Recent Posts at Visual Studio Magazine

For those who don’t know, I contribute a monthly segment over at Visual Studio Magazine called the Mobile Corner. Here are a couple of the most recent articles – I’ve cc’d them here because I feel that particularly the Enterprise Distribution article is of great value to companies looking to deploy applications internally.

  • Enterprise Distribution of Windows Phone Applications
  • Windows Phone and Windows 8.x: Designing Once for Both with XAML
  • How To Use the Windows Phone 8.1 GridView and ListView Controls
  • Breaking apart the Windows Phone 8.1 ComboBox Style and Colors

    Yesterday I had an interesting, if not a little frustrating, time pulling apart the default style of the Windows Phone 8.1 ComboBox. Before I start I’ve put together a series of images showing various states of the ComboBox:

    A – The default unfocused state of the ComboBox, showing the placeholder text
    B – The state when an item has been selected (focused and unfocused look the same)
    C – The pressed state, prior to items selection showing
    D – The expanded state when only a few items (5 or less) in the list using one of the default TextBlock styles (we’ll discuss this in a minute)
    E – The expanded state when only a few items (5 or less) in the list using a TextBlock without the Foreground color set (no selection)
    F – The expanded state when only a few items (5 or less) in the list using a TextBlock without the Foreground color set (item selected)
    G – The disabled (ie IsEnabled=false) state
    H – The expanded state when more than 5 items, which is same regardless of whether an item is selected or not (ie no selection shown)

    image

     

    Don’t Use Any of the Built In TextBlock Styles!!!

    Before we jump into look at the ComboBox styles and colors in more detail, let me briefly discuss D in more detail. For this particular scenario the combobox has 3 items in it which means that the expanded view will show the items in situ (same behaviour as the ListPicker from Windows Phone 8/8.1 Silverlight). The ItemTemplate for the ComboBox looks like the following:

    <DataTemplate x:Key="ItemsItemTemplate">
        <TextBlock Text="{Binding Property1}" Style="{StaticResource BodyTextBlockStyle}" />
    </DataTemplate>

    On face value this looks great – we have a simple TextBlock which is data bound and we’re using one of the out of the box styles, BodyTextBlockStyle. Unfortunately this inherits from BaseTextBlockStyle which sets the Foreground based on the current theme, as the following XAML snippet illustrates.

    <Style x:Key="BaseTextBlockStyle" TargetType="TextBlock">
        …….
        <Setter Property="Foreground" Value="{ThemeResource PhoneForegroundBrush}"/>
        …….
    </Style>

    <Style x:Key="BodyTextBlockStyle" BasedOn="{StaticResource BaseTextBlockStyle}" TargetType="TextBlock">
        <Setter Property="LineHeight" Value="24"/>
    </Style>

    The issue with this is that the in situ expanded view relies on Foreground being inherited from the host control, which doesn’t happen if it is explicitly set on an element (such as this case where the Foreground is being explicitly set in the TextBlock Style). The work around is simple – don’t use the built in styles, start by taking a copy of them and working with those instead eg:

    <Style x:Key="NoForegroundBaseTextBlockStyle" TargetType="TextBlock">
        <Setter Property="FontFamily" Value="{ThemeResource PhoneFontFamilyNormal}"/>
        <Setter Property="FontSize" Value="{ThemeResource TextStyleLargeFontSize}"/>
        <Setter Property="TextTrimming" Value="Clip"/>
        <Setter Property="TextWrapping" Value="WrapWholeWords"/>
        <Setter Property="LineHeight" Value="21.5"/>
        <Setter Property="LineStackingStrategy" Value="BaselineToBaseline"/>
        <Setter Property="TextLineBounds" Value="Full"/>
        <Setter Property="OpticalMarginAlignment" Value="TrimSideBearings"/>
    </Style>
    <Style x:Key="NoForegroundTextBlockStyle" BasedOn="{StaticResource NoForegroundBaseTextBlockStyle}" TargetType="TextBlock">
        <Setter Property="LineHeight" Value="24" />
    </Style>

    When I use the NoForegroundTextBlockStyle instead of D, when I expand the ComboBox I see E (no item selected) or F (item selected) instead. Note how they pick up the foreground colour, including the accent colour for the selected item.

     

    Now for the Colors

    You’d have thought that adjusting the colors throughout the combobox would be relatively straight forward. Unfortunately this is not the case but let’s start with what we can adjust without tweaking the Template of the ComboBox. Selecting the ComboBox and looking at the Properties window (VS or Blend) I can adjust the Background, Foreground and BorderBrush, as shown in the following image where I’ve set each of these to a distinct color so that we can see where they appear in the ComboBox:

    image

    The impact on the ComboBox is as follows (see image below):

    1 – In the unselected state, the Foreground color has no impact on the color of the placeholder text but the background and border colors can clearly be seen
    2 & 3 – In the selected and pressed states, again, the Foreground color has no impact
    4 – In the expanded state there are no color changes
    5 – In the selected state, when there are 5 or fewer items, the Foreground color is evident in the text
    6 – No change to the disabled state
    7 – The Foreground color is used to highlight the selected item

    image

    Clearly the use of these three colors hasn’t been applied consistently through the ComboBox states so we’re going to have to dig deeper in order to tweak things. I’ll start by looking at the Template for the ComboBox by right-clicking on the ComboBox, selecting Edit Template, Edit a Copy.

    image

    There are three components of the Template being the presenter for the header, a button and the border which will house the expanding list for when there are five or fewer items.

    image

    The Button is what is displayed when there are 5 or more items. Selecting the Button we can see that both Background and BorderBrush are set but the Foreground is inherited. I’ll update this to be data bound using Template Binding to the Foreground button.

    image

    We’ve sorted out the inconsistency in 1. This actually also sorted out the foreground color in 2 and 3. However, when the button is pressed, we still see the accent color coming through, which in most cases conflicts with the branding of our app. The question is what to replace it with…. this is an issue for another day; for now, let’s just change it to use a different static resource. Right-click on the button, select Edit Template, Edit a Copy, which will take a copy of the button template and put Blend into template editing mode. From the States window, select the Pressed state.

    image

    In the Objects and Timeline we can see that the Background on the Border element has been set to the accent color. I’ll select the Border and from the Properties window select Convert to New Resource from the Background.

    image

    I’ll name the new resource ComboBoxPressedBrush and set the color to Pink so it stands out.

    Solving 4 includes fixing a few things: Background, Border, Foreground and Selected Foreground. First things first, let’s change the white background to the background set on the ComboBox. Looking at the template it would appear that the background is already set using data binding through Template binding to the Background being set on the ComboBox. However, at least two of the States in the template are adjusting the background – in fact the error shown in Blend is the result of some developer not understanding how visual state groups work, or being too lazy to establish a working set of states. Anyhow, what we want to do in this case is actually to adjust both states to remove any changes to the background property.

    image

    In this case we need to remove the Background property from the following states:

    CommonStates - Pressed
    CommonStates - Disabled
    CommonStates – Highlighted
    DropDownStates - Opened

    Expanding the ComboBox now shows the expanded view with the correct Background color. Now onto Foreground for both the unselected and selected items. The Foreground color of the selected item is actually set correctly – it makes sense for this to be the Foreground color set on the ComboBox. However, the unselected Foreground color is currently set to a theme color, ComboBoxHighlightedForegroundThemeBrush. To override this color you can simply define another brush resource with the same name eg:

    <SolidColorBrush x:Key="ComboBoxHighlightedForegroundThemeBrush" Color="#FF00F3FF"/>

    We do also want to address the conflicting visual states by removing the Foreground property from the DropDownStates – Opened. Also, remove the BorderBrush from the CommonStates – Highlighted state, which will fix the border on the expanded area. That solves number 4.

    5 requires no changes

    Addressing 6 requires two steps. The first is to overwrite some of the built in colors that control how the ComboBox appears when it is disabled. To do this we simply create new brush resources with the same name in our application. The following resources use the same Border, Background and Foreground that I set earlier on the ComboBox, except the Opacity is set to 40%

    <SolidColorBrush x:Key="ComboBoxDisabledBorderThemeBrush" Color="#9900FF00" />
    <SolidColorBrush x:Key="ComboBoxDisabledForegroundThemeBrush" Color="#990000FF" />
    <SolidColorBrush x:Key="ComboBoxDisabledBackgroundThemeBrush" Color="#99FF0000" />

    The other part is to adjust the Disabled state of the FlyoutButton. As I did earlier I needed to edit the Template for the Button and set the disabled BorderBrush, Background and Foreground to the corresponding ComboBoxDisabled brush.

    7 requires a bit more exploration of what happens when the ComboBox expands to full screen in order to see the list of items. When this happens a flyout is displayed using the ListPickerFlyoutPresenter. The template for this control can be found in C:\Program Files (x86)\Windows Phone Kits\8.1\Include\abi\Xaml\Design\generic.xaml. Copying this template into the application resources means we can make changes, in this case to the Foreground and Background colors:

    <SolidColorBrush x:Key="ComboBoxFullScreenExpandedBackgroundThemeBrush" Color="DarkGray" />
    <SolidColorBrush x:Key="ComboBoxFullScreenExpandedForegroundThemeBrush" Color="Orange" />

    <Style TargetType="controls:ListPickerFlyoutPresenter">
        <Setter Property="Foreground" Value="{StaticResource ComboBoxFullScreenExpandedForegroundThemeBrush}" />
        <Setter Property="Background" Value="{StaticResource ComboBoxFullScreenExpandedBackgroundThemeBrush}" />
        ….

    The only thing this doesn’t affect is the header on the flyout page which still appears in white. To get this to use the Foreground value I just set I need to modify the FlyoutPickerTitleTextBlockStyle built in style (which is also in the generic.xaml file) by copy it into the application resources and altering the BasedOn value to use the NoForegroundBaseTextBlockStyle defined earlier.

    <Style x:Key="FlyoutPickerTitleTextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource NoForegroundBaseTextBlockStyle}">
        ……
    </Style>

    With these changes made we’ve got much better control over how the ComboBox displays text and how the border, background and foreground colors are applied.

    image

     

    Hopefully in this post you’ve seen how you can jump in and alter colors throughout the ComboBox templates. There are a series of built in colors both in generic.xaml and themeresources.xaml (C:\Program Files (x86)\Windows Phone Kits\8.1\Include\abi\Xaml\Design) which can be overwritten to do simple changes but sometimes you need to modify the underlying templates.

    Windows Phone 8.1 APPX Code Signing Weird Error When Installing

    Over the last couple of days I’ve been trying to diagnose what we were doing wrong when code signing a Windows Phone 8.1 APPX file in preparation for enterprise distribution. The signing process completes successfully. However, when we go to install the application on either device or emulator we were seeing weird errors (see image below that quotes an exception code of 0x80073CF9).

    clip_image002

    SOLVED: It turns out that there is an issue with the signing process but nothing related to what we were doing. It’s actually related to the version of the tools we’re using. Here’s a list of the toolsets that apparently work/don’t work:

    Visual Studio 2013 with Update 2 RC – WORKS
    Visual Studio 2013 with Update 2 RTM – DOESN’T WORK
    Visual Studio 2013 with Update 3 RC – WORKS

    So you either need to regress to the RC of Update 2, or go to the RC of Update 3.

    Side Note: If you see errors relating to a missing token, you’re probably attempting to install the package by calling AddPackageAsync from within an application that isn’t signed (ie a developer build pushed out using either the application deployment tool, or via Visual Studio). If you sign the application doing the installation and then install it, you should see the the call to AddPackageAsync will work for correctly signed XAP and APPX. This is a breaking change from Windows Phone 8.0 where this method worked regardless of whether the installer app was signed or not.

    Using Build it Beta to Test and Deploy your Windows Phone Applications

    Over the last year we’ve been working on Build it Beta to assist Windows Phone developers deploy and test their applications. To get started, follow the setup instructions for Build it Beta

    image

    Here’s a bit more information on each step:

    Step 1: The Build it Beta application is available in both the Windows and Windows Phone Stores. In order to test an application on your Windows Phone device, the first step is to download the Build it Beta application from the store.

    Step 2: After downloading and installing Build it Beta you then need to run and sign into Build it Beta. You can choose between one of the supported social network providers (Facebook, Twitter, Microsoft, Google) and use an existing or create a new set of credentials. You need to supply a valid email address so that we can identify your account. When you want to test and application you can simply send your application to upload @ builditbeta.com from the email address you entered. We’ll send you a confirmation after the application is available for testing. After signing in, you should be prompted to return to the setup instructions. Alternatively press and hold the back button and switch back to Internet Explorer where you should still have the setup instructions.

    Step 3: Install the Built to Roam enterprise deployment certificate. This certificate is required in order to install applications you want to test. Rather than deploying applications via the Windows Phone store, where they’re signed with a pre-trusted certificate, in Build it Beta all applications are currently signed using the Built to Roam enterprise deployment certificate. Installing this certificate won’t affect your ability to install applications from the Windows Phone store, nor does it affect any other enterprise enrolment you may have (eg via an MDM provider).

    Step 4: Install the Build it Beta Installer. Due to both technical and policy limitations on applications installed from the Windows Phone Store, Build it Beta relies on a secondary application to install the applications you want to test. Clicking the link in the setup instructions should prompt you to install this application. Unfortunately there isn’t a progress indicator or confirmation that it has been installed successfully – give this step a minute or two before moving on.

    Step 5: Launch the Build it Beta Installer. This will run the installer and pair it with the main Build it Beta application. Once you’ve completed this process you’re good to go – start sending your applications to Build it Beta to test them.

     

    Testing an application

    When you have an application that you want to test you can send it to Build it Beta a number of ways:

    Email – Simply email your xap or appx file to upload @ builditbeta.com. You’ll get a confirmation message back once the application has been ingested.

    Upload – If you have Build it Beta for Windows installed you can simply double-click your xap file. The application will be uploaded to Build it Beta.

    Attachment – Rename your xap file to .betaxap and email it to someone you want to test your application. Clicking the attachment will upload the application via Build it Beta for Windows Phone and make it available for the tester.

    Taking Visual States Cross Platform to iOS and Android with Xamarin

    Last Friday at the Windows Phone 8.1 developer training, run by Microsoft, Nokia Microsoft and Built to Roam, we asked the room how many people used Blend and knew about Visual States. I was shattered to see very few people even knew what a Visual State was, let alone use them in their code. Visual States have to be one of the most useful aspects of the XAML system allowing you to define different states for not only your pages but also controls and user controls that you create.

    On Tuesday night before the Sydney Mobile .NET Developer Meetup I was talking with Lewis Benge about how developers on other platforms control aspects of their user interface. The consensus is that it’s very reactive in that as elements of their data model, or in the case of mvvmcross elements of the view model, change elements of the UI are adjusted. For example if you were displaying some form of a loading indicator whilst some data was being retrieved from a service, when the call was complete, the progress indicator would be hidden. In this simple case you might think that it’s just one line of code to show or hide the progress indicator but now repeat this two or three times and all of a sudden you have UI control code littered throughout your application logic. In the XAML world we’d simply define these as visual states and we’d move between those states as required. In fact, as you’ll see we can even represent these states within our view model so that the state, not the visual representation of the states, form part of our application logic (and can be isolated and tested independently as it can sit nicely within a PCL).

    Ok, now for a more concrete example:

    - File –> New Project –> Windows Phone application

    - Add New Project –> Android application

    (you can repeat for iOS if you want)

    - Add New Project – Portable Class Library

    - Manage NuGet –> Add Mvvmcross to all projects, and follow “ToDos” as required for each project

    >> At this point, you want to make sure that both your Windows Phone and Android applications build and can be run. They should both launch FirstView and contain a textbox and label with databinding working so that you can change the text in the textbox and it is updated in the label.

    Blending some Visual States

    We’re going to add a progress bar and a piece of text to say “Loading….” whilst data is being loaded.

    - Right-click the Windows Phone project and select Open in Blend

    - Add a progress bar and texblock to the contentpanel element to give you the following xaml – note that both elements are currently collapsed

    <Grid x:Name="ContentPanel"
            Grid.Row="1"
            Margin="12,0,12,0">
        <ProgressBar x:Name="progressBar"
                        Visibility="Collapsed" />
        <TextBlock x:Name="textBlock"
                    TextWrapping="Wrap"
                    Text="Loading..."
                    VerticalAlignment="Center"
                    HorizontalAlignment="Center"
                    Margin="0,-25,0,0"
                    Visibility="Collapsed" />
    </Grid>

    - In the States tool windows, click the “Add state group” button in the icon bar. Call the state group “LoadingStates” (this name is somewhat irrelevant as it’s never used other than in Blend to allow you to differentiate if you have multiple state groups)

    - Click the “Add state” button twice to generate states “Loading” and “Loaded”

    - With the Loading state selected (there should be a red border around the main design surface indicating that you’re in state editing mode) set both textblock and progressbar to visible, and set the isindeterminate property to true. If you look at the xaml you should see the following states defined:

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="LoadingStates">
            <VisualState x:Name="Loading">
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                    Storyboard.TargetName="progressBar">
                        <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                                <Visibility>Visible</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                        </DiscreteObjectKeyFrame>
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(ProgressBar.IsIndeterminate)"
                                                    Storyboard.TargetName="progressBar">
                        <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                                <System:Boolean>True</System:Boolean>
                            </DiscreteObjectKeyFrame.Value>
                        </DiscreteObjectKeyFrame>
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                    Storyboard.TargetName="textBlock">
                        <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                                <Visibility>Visible</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                        </DiscreteObjectKeyFrame>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>
            <VisualState x:Name="Loaded" />
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

    - If you switch between the Loading and Loaded states in Blend you should see the elements show and hide as expected. Now we need to wire up some logic to switch between these states at runtime.

    - Return to Visual Studio and go to the code-behind file for the FirstView (Windows Phone project).

    - Add the following code to the OnNavigatedTo method:

    protected async override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        VisualStateManager.GoToState(this, "Loading", true);
        await Task.Delay(2000);
        VisualStateManager.GoToState(this, "Loaded", true);
    }

    - Run the Windows Phone application and observe the application switching between the two states

    - Now we need to move this logic one step further away from the UI layer and have it contained within our ViewModel. We’ll also try to eliminate those pesky string literals. To do this we’ll define an enumeration in code so that we can refer to our VisualStates – the name of the enumeration doesn’t matter but the name of the enumeration values needs to match the names of the states defined in Blend

    public enum FirstStates
    {
        Base,
        Loading,
        Loaded
    }

    - To move our state logic into the ViewModel we’ll need a way to trigger the actual state change in the UI layer (ie the view). For this we’ll expose an event on the ViewModel which will include the name of the state that we want the view to transition to. We’ll start by defining a StateEventsArgs class which we’ll use to wrap the name of the state. This class includes a couple of helper methods to make it easy to generate an instance from an enumeration value, and to return an enumeration value. You might ask why we’re converting to and from strings – we’ll come back to this!

    public class StateEventArgs : EventArgs
    {
        public string StateName { get; private set; }

        public static StateEventArgs Create<TState>(TState state) where TState : struct
        {
            return new StateEventArgs {StateName = state.ToString()};
        }

        public TState AsState<TState>() where TState : struct
        {
            TState state = default(TState);
            Enum.TryParse(StateName, true, out state);
            return state;
        }
    }

    - Update the FirstViewModel to raise a StateChanged event as follows:

    public void OnStateChanged(FirstStates state)
    {
        if (StateChanged != null)
        {
            StateChanged(this, StateEventArgs.Create(state));
        }
    }
    public override async void Start()
    {
        base.Start();
        await Task.Yield(); // Attach state changed event handler

        OnStateChanged(FirstStates.Loading);
        await Task.Delay(5000);
        OnStateChanged(FirstStates.Loaded);
    }
    public event EventHandler<StateEventArgs> StateChanged;

    - Now, in the code behind for our FirstView we can amend the OnNavigatedTo method to wire up a StateChanged event handler:

    protected async override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        (ViewModel as FirstViewModel).StateChanged += FirstView_StateChanged;
    }

    void FirstView_StateChanged(object sender, StateEventArgs e)
    {
        VisualStateManager.GoToState(this, e.StateName, true);
    }

    - When you run this, there is a 5 second delay during the Start method in the FirstViewModel during which the Loading state should be visible. There after it should revert to the Loaded state.

    - Let’s flip across to our Android project and amend the FirstView to include the following xml.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="
    http://schemas.android.com/apk/res/android"
        xmlns:local="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <EditText
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="40dp"
            local:MvxBind="Text Hello" />
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="40dp"
            local:MvxBind="Text Hello" />
        <Button
            android:id="@+id/MyButton"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/Hello" />
        <ProgressBar
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/progressBar1" />
    </LinearLayout>

    - Note that unlike in XAML for Windows Phone we can’t define the visual states in xml. Instead we define them as a set of Actions which will be invoked when transitioning to a particular state. In this case we’re setting the progress bar to indeterminate and changing the button color for Loading state. You’ll notice that unlike in XAML where we could rely on the state manager to revert state changes (ie Loaded state simply reverses any changes applied by the Loading state), here we have to be explicit about all changes we want to occur.

    private IDictionary<FirstStates, Action> states;
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.FirstView);

        var button = FindViewById<Button>(Resource.Id.MyButton);
        button.Click += (s,e) => ViewModel.Start();

        var progress = FindViewById<ProgressBar>(Resource.Id.progressBar1);

        states = new Dictionary<FirstStates, Action>()
        {
            {FirstStates.Loading, () =>
            {
                progress.Indeterminate = true;
                button.SetTextColor(new Color(0,255,0));
            }},
            {FirstStates.Loaded, () =>
            {
                progress.Indeterminate = false;
                button.SetTextColor(new Color(255,0,0));
            }}
        };
    }

    - The final piece is to wire up an event handler to the StateChanged event, the same as we did for Windows Phone:

    protected override void OnViewModelSet()
    {
        base.OnViewModelSet();

        (ViewModel as FirstViewModel).StateChanged += FirstView_StateChanged;
    }

    void FirstView_StateChanged(object sender, StateEventArgs e)
    {
        var state = e.AsState<FirstStates>();
        var change = states[state];
        change();
    }

    - When the StateChanged event is trigger, we find the appropriate Action by looking in the state Dictionary. The Action is then invoked to apply the appropriate visual changes.

    In this post I’ve walked you through the basics of how you can use visual states across both Android and Windows Phone, controlled from within your view models. This same model can be applied to iOS and of course the code for wiring up the state changed event can be abstracted into base view models and base views so you don’t need to add it to every page.

    Using Universal Share Projects for Windows Phone Silverlight 8.0 and 8.1 Upgrade Path

    Of course with the announcement of Windows Phone 8.1 XAML applications (ie applications for WP8.1 written in Windows XAML) and support for Universal applications, not everyone is going to immediately rebuild their Windows Phone application. Instead, existing developers need a mechanism to upgrade to the new runtime to leverage the new features without having to redeveloper all their pages. This is where Silverlight 8.1 applications come in.

    There is only minimal support within Visual Studio to support developers upgrading to Silverlight 8.1, allowing them to “Retarget to Windows Phone 8.1”.

    image

    Retargeting works well and typically your application will continue to run. However, in most cases you’ll want to maintain both a Silverlight 8.0 and 8.1 versions of your application. An alternative is to create a copy of your Silverlight 8.0 application and upgrade that – now you have two versions of your application that you have to support. Luckily this is an area where the new Shared project support, added to enable universal applications across Windows Phone and Windows, can be used to maintain code that is used by both a Silverlight 8.0 and 8.1 application (sort of Linked files on steroids).

    Steps:

    - Install the Shared Project Reference Manager (http://visualstudiogallery.msdn.microsoft.com/315c13a7-2787-4f57-bdf7-adae6ed54450) – this makes creating Shared Projects much easier

    - Create a new Shared Project eg MyApplication.Shared

    - Unload you Windows Phone project

    - Edit your Windows Phone project file

    - Add a Shared Project Reference via the right-click shortcut menu on your Windows Phone project (Note: for some reason adding a shared project reference isn’t supported for Windows Phone projects, so we need to do it the manual way)

    - Add Import to end of project file which references the shared project file eg

    <Import Project="..\MyApplication.Shared\MyApplication.Shared.projitems" Label="Shared" />

    - Reload your Windows Phone project – you should see a reference to your Shared project under References node

    image

    - Move as many files as possible from your Windows Phone project into the Shared project

    - Note that you may experience some of these issues:

    > AppResources.resx doesn’t move easily. You’ll need to make sure that both the resx and the designer.cs file are moved and that the Build Action is correct (resx file should have a Build Action of Embedded Resource and a Custom Tool of PublicResXFileCodeGenerator). You also need to remove the “.Resources” from the name of the resource being loaded and the namespace.

    > You need to keep any images referenced in the WMAppManifest.xml file in the Windows Phone project. This is ApplicationIcon.png and FlipCyleTileMedium.png by default

    > You still need an App.xaml file in your Windows Phone project

    - Check that your Windows Phone application builds and runs (fix any build errors!)

    - In Windows Explorer take a copy of your Windows Phone application and rename the folder and project files eg MyApplication.SL81

    - Add the copied project into the same solution

    - Right click on the project you just added and select “Retarget to Windows Phone 8.1”. Your solution structure should now look similar to the following

    image

    - Build and run your new Windows Phone 8.1 application

    The upshot after all this is that you have a Shared project where you can store shared files across your Windows Phone Silverlight 8.0 and 8.1 applications.

    XAML and Databinding Debugging for Windows and Windows Phone

    A question that came up today during the //learn/ event was how to debug data binding in Windows and Windows Phone projects.Normally I start by checking out the Output window – in most cases any issue with data binding is usually a naming issue, which will result in a bindingexpression path error in the Output window as follows:

    Error: BindingExpression path error: 'test' property not found on 'App4.MainViewModel, App4, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='test' DataItem='App4.MainViewModel, App4, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')

    I was reminded that Xmlspy is a great tool for diagnosing XAML issues, as well as data binding expressions. I downloaded the latest version and was surprised to see that there is full support for all types of Windows Phone 8.1 applications. The only issue I saw was getting it to attach to Windows Phone applications but this was due to my firewall getting in the way. Here’s how you can check and fix this issue:

    • Open the XAML Spy Explorer window (View menu–> Other Windows –> XAML Spy Explorer)
    • Click on the “cog” icon in the window toolbar
    • Find the “Enable remote debugging” option and set it to Yes. You’ll be prompted to permit elevated privileges (I assume to configure firewall).

    image 

    Now you should be good to debug your application on the emulator/device. The XAML Spy Explorer window will automatically populate with information about your application

    image

    Note that you can debug much more than just XAML, including sensors, storage and package deployment information.