Nick's .NET Travels

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

Navigation Service for Cross Platform Page/View Navigation from View Model

I already have a solution for allowing the view model to jump back onto the UI thread using the UIContext. However, I currently don’t have a mechanism that will allow one view model initiate navigation to a new page/view. What I want is the ability for one view model to request navigation by specifying the destination view model. Of course, this needs to work cross platform. Let’s take a look at the basics of how this could work – there are essentially two strategies that most mvvm style navigation frameworks use: The first is by convention where the lookup for the destination page/view is based on the name of the target view model; the second is by defining a mapping between view models and the corresponding page/view. In this case I’m going to go with the latter – In the Core library I define a couple of interfaces and an abstract implementation:

public interface INavigateService
{
    void Navigate<TViewModel>() where TViewModel : IDataViewModel;
}

public interface INativeNavigateService<TView> : INavigateService
    where TView : class,new()
{
    void Register<TViewModel, TViewType>() where TViewType : TView;
}

public abstract class CoreNavigateService<TView> : INativeNavigateService<TView> where TView : class, new()
{
    private readonly IDictionary<Type, Type> viewDictionary = new Dictionary<Type, Type>();

    protected Type ViewType<TViewModel>()
    {
        Type viewType = null;
        viewDictionary.TryGetValue(typeof(TViewModel), out viewType);
        return viewType;
    }

    public void Register<TViewModel, TViewType>() where TViewType : TView
    {
        viewDictionary[typeof(TViewModel)] = typeof(TView);
    }

    public void Navigate<TViewModel>() where TViewModel : IDataViewModel
    {
        var navType = ViewType<TViewModel>();
        NavigateToView(navType);
    }

    protected abstract void NavigateToView(Type viewType);
}

Next, in the client projects, I define a class that inherits from CoreNavigateService and implements the NavigateToView method. Here is the Windows Platform implementation:

public class WindowsPlatformNavigationService : CoreNavigateService<Page>
{
    protected override void NavigateToView(Type viewType)
    {
        (Window.Current.Content as Frame).Navigate(viewType);
    }
}

The ApplicationStartup method now looks like:

public void ApplicationStartup()
{
    CoreApplication.Startup(builder =>
    {

        builder.RegisterType<SignalRFactory>().As<ISignalR>();
#if NETFX_CORE
        builder.RegisterType<UniversalUIContext>().As<IUIContext>();

        builder.RegisterType<WindowsPlatformNavigationService>().SingleInstance().As<INavigateService>();
#endif
    });

    var navService = ServiceLocator.Current.GetInstance<INavigateService>() as WindowsPlatformNavigationService;

#if NETFX_CORE
    navService.Register<MainViewModel,MainPage>();
    navService.Register<SecondViewModel,SecondPage>();
#endif
}

Both the IDataViewModel, BaseViewModel and ViewModelLocator need to be extended to include an INavigateService property called NavigateService. Now from within the view model, navigation can be invoked by calling NavigateService.Navigate<SecondViewModel>()

Adding a Background Task to the Windows Platform Applications

At some point you’re likely to want to run code in the background – this might be to update live tiles, or to do periodic synchronization of data. In this post I’ll add a background task to the Windows platform applications. I’ll start by adding a new Windows Runtime Component to the solution.

image

As a Windows RT component there are some additional restrictions on the definition of types and the way methods are exposed. However, I can still add a reference to the background project to the Core library of the application. As the Core library encapsulates all the logic for the application this should be sufficient to perform background operations such as synchronizing data or updating tile contents.

Next I want to add a reference from the Universal applications (Windows and Windows Phone) to the background task project. Once done, it’s time to create the actual task that will be invoked in the background. I’ll replace the default Class1.cs with SyncTask.cs with the following templated structure:

public sealed class SyncTask : IBackgroundTask
{
    private BackgroundTaskCancellationReason cancelReason = BackgroundTaskCancellationReason.Abort;
    private volatile bool cancelRequested = false;
    private BackgroundTaskDeferral deferral = null;
    //
    // The Run method is the entry point of a background task.
    //
    public async void Run(IBackgroundTaskInstance taskInstance)
    {
        try
        {
            Debug.WriteLine("Background " + taskInstance.Task.Name + " Starting...");

            //
            // Get the deferral object from the task instance, and take a reference to the taskInstance;
            //
            deferral = taskInstance.GetDeferral();
            //
            // Associate a cancellation handler with the background task.
            //
            taskInstance.Canceled += OnCanceled;

            //
            // Query BackgroundWorkCost
            // Guidance: If BackgroundWorkCost is high, then perform only the minimum amount
            // of work in the background task and return immediately.
            var cost = BackgroundWorkCost.CurrentBackgroundWorkCost;

            if (cost == BackgroundWorkCostValue.High)
            {
                // Only push changes
            }
            else
            {
                // Do full sync
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
        finally
        {
            if (deferral != null)
            {
                deferral.Complete();
            }
        }
    }

    //
    // Handles background task cancellation.
    //
    private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
    {
        //
        // Indicate that the background task is canceled.
        //
        cancelRequested = true;
        cancelReason = reason;
        Debug.WriteLine("Background " + sender.Task.Name + " Cancel Requested...");
    }
}

I also need to define this task as a background task in the Declarations section of the project manifest files. In this case we’re going to be triggering the background task based on a system event.

image

Lastly, the background task needs to be registered. For this I’m using this BackgroundTaskManager class which wraps the registration process for tasks.

public class BackgroundTaskManager
{
    /// <summary>
    /// Register a background task with the specified taskEntryPoint, name, trigger,
    /// and condition (optional).
    /// </summary>
    /// <param name="taskEntryPoint">Task entry point for the background task.</param>
    /// <param name="name">A name for the background task.</param>
    /// <param name="trigger">The trigger for the background task.</param>
    /// <param name="condition">An optional conditional event that must be true for the task to fire.</param>
    public static async Task<BackgroundTaskRegistration> RegisterBackgroundTask(String taskEntryPoint, String name, IBackgroundTrigger trigger, IBackgroundCondition condition)
    {
        BackgroundExecutionManager.RemoveAccess();
        var hasAccess = await BackgroundExecutionManager.RequestAccessAsync();
        if (hasAccess == BackgroundAccessStatus.Denied) return null;

        var builder = new BackgroundTaskBuilder();
        builder.Name = name;
        builder.TaskEntryPoint = taskEntryPoint;
        builder.SetTrigger(trigger);
        BackgroundTaskRegistration task = builder.Register();
        Debug.WriteLine(task);

        return task;
    }

    /// <summary>
    /// Unregister background tasks with specified name.
    /// </summary>
    /// <param name="name">Name of the background task to unregister.</param>
    /// <param name="cancelRunningTask">Flag that cancels or let task finish job</param>
    public static void UnregisterBackgroundTasks(string name, bool cancelRunningTask)
    {
        //
        // Loop through all background tasks and unregister any with SampleBackgroundTaskName or
        // SampleBackgroundTaskWithConditionName.
        //
        foreach (var cur in BackgroundTaskRegistration.AllTasks)
        {
            if (cur.Value.Name == name)
            {
                cur.Value.Unregister(cancelRunningTask);
            }
        }
    }
}

The actual registration is done when the application starts. In this case I’m going to cheat a little and include it in the OnNavigatedTo for the MainPage:

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

    try
    {
        BackgroundTaskManager.UnregisterBackgroundTasks("Background Sync Task", true);
        BackgroundTaskRegistration taskReg =
            await BackgroundTaskManager.RegisterBackgroundTask(typeof(SyncTask).FullName,
                "Background Sync Task",
                new SystemTrigger(SystemTriggerType.InternetAvailable, false),
                null);
    }
    catch (Exception ex)
    {
        // Swallow this to ensure app doesn't crash in the case of back ground tasks not registering
        Debug.WriteLine(ex.Message);
    }
}

Notice that this task is registering interest in the InternetAvailable trigger, allowing the background task to be invoked whenever connectivity changes. Note that this process works for both Windows and Windows Phone Universal projects.

Update:

What I forgot to include here is that if you want tasks to run in the background on the Windows platform you need to make them lock screen enabled. To do this set the “Lock screen notifications” to either Badge or Badge and Tile Text.

image

This will cause a couple of red circles indicating issues with the configuration of the application. The first is that you need to specify either location, timer, control channel or push notifications in the Declarations tab – I’ve chosen to check the push notification checkbox

image

The other requirement is a badge logo – I’ve only specified one of the three options. I’d recommend providing all three if you are serious about delivering a high quality application.

image

Update 2:

When it actually came to run this I must confess I ran into an issue with a typo. Back on the second screenshot an observant reader would have noticed the spelling mistake on the namespace RealEstateInspector. When you attempt to register the service I saw something similar to the following:

image

Full exception details:

System.Exception occurred
  HResult=-2147221164
  Message=Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))

Saving Image to Blob Storage Using Shared Access Signature

In this post I’m  going to bring together a couple of my previous posts that discuss retrieving and saving images, and retrieving a Shared Access Signature from a controller which will allow me to write to a particular container within Blob Storage. To complete the implementation I’ll use the Windows Azure Storage library from NuGet – it only installs for Windows platforms as there’s no PCKL or Xamarin support for this library currently.

image

As the Windows Azure Storage library is current platform specific, I’ll need to wrap it in a simple interface that makes it easy for me to write data to Blob Storage – I’ll come back to that. For the time being I’m just going to retrieve the SAS and use it along with the storage library to upload an image. So I’ll start by invoking the sharedaccesssignature controller using the GET verb as I want to ensure the container is created if it doesn’t already exist. This will return a SAS which I can use in the upload process.

public async Task<string> RetrieveSharedAccessSignature()
{
    var sas = await MobileService.InvokeApiAsync<string>("sharedaccesssignature", HttpMethod.Get,
        new Dictionary<string, string> { { "id", "test" } });
    return sas;
}

Next I want to capture an image, in this case picking a photo, and uploading it to a specified blobg.

private async void CaptureClick(object sender, RoutedEventArgs e)
{
    var picker = new MediaPicker();
    var sas = string.Empty;
    using (var media = await picker.PickPhotoAsync())
    using (var strm = media.GetStream())
    {
        sas = await CurrentViewModel.RetrieveSharedAccessSignature();

        Debug.WriteLine(sas);

        // Get the URI generated that contains the SAS
        // and extract the storage credentials.
        var cred = new StorageCredentials(sas);
        var imageUri = new Uri("
https://realestateinspector.blob.core.windows.net/test/testimage.png");

        // Instantiate a Blob store container based on the info in the returned item.
        var container = new CloudBlobContainer(
            new Uri(string.Format("
https://{0}/{1}",
                imageUri.Host, "test")), cred);

        // Upload the new image as a BLOB from the stream.
        var blobFromSASCredential = container.GetBlockBlobReference("testimage.png");
        await blobFromSASCredential.UploadFromStreamAsync(strm.AsInputStream());
    }

}

Clearly this code isn’t well factored but it’s here as a quick example of how you can use a SAS to upload content to blob storage.

ViewModel Refactoring, INotifyPropertyChanged and Running on UI Context with Dispatcher

In a previous post I showed how to use SignalR as one option for providing feedback to the client application during a long running service operation. However, I didn’t display this on the UI because that would have made the blog post long and complicated as I tried to explain propagating a change from a non-UI thread, back onto the UI thread so it could be displayed within the app. In this post I’m going to do just that – what’s interesting is that each platform handles this scenario slightly different with some caring about thread affinity, whilst others do not.

Firstly, I’ll update the layout to include a TextBlock that’s going to display the progress:

<TextBlock Text="{Binding Progress}" />

In this case databinding to the Progress property on the MainViewModel:

private string progress;
public string Progress
{
    get { return progress; }
    set
    {
        if (Progress == value) return;
        progress = value;
        OnPropertyChanged();
    }
}

Note that as this property changes it calls the OnPropertyChanged method which will be used to raise the PropertyChanged event specified in the INotifyPropertyChanged interface – this is what the XAML data binding framework uses to detect when bound properties are changed. In this case I’m going to implement this interface in BaseViewModel, and have MainViewModel inherit from BaseViewModel, rather than implement it in every view model.

public class MainViewModel:BaseViewModel  { … }

public class BaseViewModel:INotifyPropertyChanged
{
   
public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));

    }
}

Now, let’s modify the delegate that gets invoked when we receive an update from the service. Previously we just had Debug.WriteLine(msg), let’s change that to  Progress=msg. When you run this in your Universal Windows application – BANG – Exception due to an attempt to update the UI (ie the Text attribute on the TextBlock) from a non-UI thread. Interestingly doing the same thing in the WPF application doesn’t throw the same exception. In order to update the Progress property, we first need to jump back onto the UI thread, which is fine, if we were working directly with the Page/View. However, we don’t have any notion of a Dispatcher, UI threads etc from within the MainViewModel. This sounds like another scenario for a dependency injected implementation, so here goes:

My BaseViewModel is extended to include a UIContext object:

private readonly UIContext context=new UIContext();

public UIContext UIContext

{
    get { return context; }
}

The UIContext object wraps and abstracts away the loading of an implementation of IUIContext:

public interface IUIContext
{
    Task RunOnUIThreadAsync(Func<Task> action);
}

public class UIContext
{
    private IUIContext runContext;
    private IUIContext RunContext
    {
        get
        {
            if (runContext == null)
            {
                runContext = ServiceLocator.Current.GetInstance<IUIContext>();

            }
            return runContext;
        }
    }

    public async Task RunAsync(Action action)
    {
        await RunAsync(async () => action());
    }

    public async Task RunAsync(Func<Task> action)
    {
        var context = RunContext;
        await context.RunOnUIThreadAsync(action);
    }
}

Of course, we now need an implementation of IUIContext for our Universal Windows application:

public class UniversalUIContext : IUIContext
{
    public async Task RunOnUIThreadAsync(Func<Task> action)
    {
        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,async  () => await action());
    }
}

And this needs to be registered with Autofac in the ClientApplicationCore – note the use of the NETFX_CORE compilation attribute.

CoreApplication.Startup(builder =>
{
    builder.RegisterType<SignalRFactory>().As<ISignalR>();
#if NETFX_CORE
    builder.RegisterType<UniversalUIContext>().As<IUIContext>();
#endif
});

And finally I need to go back to my initial progress statement and update it from msg => Progress = msg, to the following:

async msg =>
    await UIContext.RunAsync(() =>
    {
        Progress = msg;
    })

This issue isn’t specific to Universal applications, and you should always make sure you have access to the UI thread when making UI changes (such as updating data bound properties).

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 WPF Client with Azure Active Directory Authentication and Azure Mobile Service

In today’s post I was going to cover adding Azure AD authentication to my iOS project but I don’t have my Mac build machine handy so there’s a bit of a change of plans. Today I’m going to add a WPF desktop application to my solution and catch it up to where the other client applications are up to. I’ll start by creating the WPF Application.

image

At this point I realised that I missed setting the framework in the Add New Project dialog, so I opened the Properties pane of the application and on the Application tab I set the Target framework to .Net Framework 4.5.

image

Next we need to add references to the following solution projects:

- RealEstateInspector.Core

- RealEstateInspector.Shared.Client

And then add reference to both the ADAL and Mobile Service SqliteStore packages. From the downloads page on sqlite.org you’ll also need to download the “32-bit DLL (x86) for SQLite” which is under the Precompiled Binaries for Windows heading. Unblock and Extract the zip file and add the sqlite3.dll file to the new WPF project, setting the Build Action to Content and setting the Copy to Output Directory to Copy always.

I also need to check the Prefer 32-bit checkbox and define the DESKTOP compilation symbol for All Configurations.

image

I’ll add the following XAML markup to the MainWindow.xaml

<Window x:Class="RealEstateInspector.Desktop.MainWindow"
        xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <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>
</Window>

And the following code to the MainWindow.xaml.cs

public partial class MainWindow : IWin32Window
{
    public IntPtr Handle
    {
        get
        {
            var interopHelper = new WindowInteropHelper(this);
            return interopHelper.Handle;
        }
    }
    public MainWindow()
    {
        InitializeComponent();

        Loaded += MainWindow_Loaded;
    }
    public MainViewModel CurrentViewModel
    {
        get { return DataContext as MainViewModel; }
    }
    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        var vm = new MainViewModel();
        DataContext = vm;
    }

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

I also had to make some minor changes to the AuthenticationHelper

public static class AuthenticationHelper
{

    public static async Task<string> Authenticate(
#if DROID
    Android.App.Activity callerActivity
#elif DESKTOP
IntPtr callerHandle
#endif
        )
    {
        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()
#elif DROID
                    new AuthorizationParameters(callerActivity)
#elif DESKTOP
                        new AuthorizationParameters(PromptBehavior.Auto, callerHandle)
#else
                        new AuthorizationParameters(PromptBehavior.Auto, false)
#endif
                    );
            Debug.WriteLine(authResult != null);

            return authResult.AccessToken;

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

And that’s it, the WPF desktop application can be run up, the user can sign in and properties are synchronized before being displayed.

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).

Accessing Authentication Required Mobile Service

Previously I added security to my mobile service by Requiring Authentication on the Azure Mobile Service and in my previous post I showed how you can manually request an authorization and access token. In addition to exploring the id_token (which is the unassigned JWT) if you explore the access_token you can see that it has a claim pertaining to the Mobile Service

image

We’re going to use this value to authenticate against our Mobile Service, which will allow us to query the data. In my MainViewModel I’m going to adjust the code slightly to use this access token value – this is just to demonstrate how the access token is going to be used, of course in a real world application you’ll need to authenticate the user using a web browser in the application in order to retrieve the access_token, but more on that later. My LoadPropertyData method now looks like this (the access_token value has been shortened to make the code more readable but was copied directly from the response in fiddler:

public async Task LoadPropertyData()
{
    var access_token="eyJ0eXAiOiJKV1Qi---------TOF9eYN97Jey-r_oDq5anQ";
    var jobj = new JObject();
    jobj["access_token"] = access_token;
    var access = await MobileService.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, jobj);
    Debug.WriteLine(access!=null);
    var data = new MobileServiceSQLiteStore("inspections.db");
    data.DefineTable<RealEstateProperty>();
    data.DefineTable<Inspection>();

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

    await MobileService.PullLatestAsync<RealEstateProperty>();
    await MobileService.PullLatestAsync<Inspection>();

    var props = await MobileService.GetSyncTable<RealEstateProperty>().ToListAsync();
    foreach (var prop in props)
    {
        Properties.Add(prop);
    }
}

This code can be run and will retrieve the properties in the Mobile Service, at least whilst the access_token remains valid

Thinking About MVVM and View Models

At this point I’m rather postponing the inevitable need to add an MVVM framework into my application. I’m not going to delve into into what MVVM is as I think that’s a conversation for another day and there are existing sites/reference that more than do this topic justice. However, enough to say that there is an important role for MVVM in the mobile app development space, particularly with Windows platform and Xamarin.Forms where we can use data binding. The reason I’ve been putting it off is that in the past I would have gone the MVVMcross route but I’m yet to see this work against Xamarin.Forms. This leaves me with the need to evaluate other frameworks such as MvvmLite (a long term player in the MVVM space), ReactiveUI and Calcium. I’m still on the hunt for the next killer framework that I’ll use religiously, in the meantime I’m going to avoid the need to make a decision by starting by manually creating and assigning the viewmodel for the main page of the application.

To abstract our view models away from the specifics of how the data is going to be presented (ie the premise of MVVM) I’ll create a separate Portable Class Library which will contain my view models.

image

When setting the targets, don’t forget to include Windows Phone Silverlight 8, otherwise you won’t be able to use the PCL from the XForms project.

image

Into this library I’ll create a ViewModels folder and then my first view model, MainViewModel. I’ll then migrate the logic that I had in my shared code from my Windows platform applications across into this view model. This includes

- Adding NuGet package reference to the Microsoft.WindowsAzure.Mobile and Microsoft.WindowsAzure.Mobile.SQLiteStore (just add the latter as the former will be added automatically)

- Add reference to the shared entities project so that the view models can access the data entities

- Remove references to the shared entities projects from the Windows platform projects (otherwise you’ll end up with type reference errors since you’ll effectively have two copies of the entity classes).

- Move the MobileServiceClientExtensions class I created previously into the new portable class library

- Add reference to the new PCL to the XForms and Windows platform projects.

The final outcome is a view model which loads all the properties when the LoadPropertyData method is invoked

public class MainViewModel
{

    public static MobileServiceClient MobileService = new MobileServiceClient(
        "https://realestateinspector.azure-mobile.net/",
        "wpxaIplpeX-----------------------------g12"
        );

    private ObservableCollection<RealEstateProperty> properties = new ObservableCollection<RealEstateProperty>();

    public ObservableCollection<RealEstateProperty> Properties
    {
        get { return properties; }
    }

    public async Task LoadPropertyData()
    {
        var data = new MobileServiceSQLiteStore("inspections.db");
        data.DefineTable<RealEstateProperty>();
        data.DefineTable<Inspection>();

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

        await MobileService.PullLatestAsync<RealEstateProperty>();
        await MobileService.PullLatestAsync<Inspection>();

        var props = await MobileService.GetSyncTable<RealEstateProperty>().ToListAsync();
        foreach (var prop in props)
        {
            Properties.Add(prop);
        }
    }
}

Let’s return to our Windows platform applications and wire up a basic interface. In the MainPage.xaml for the Windows project I’ll add some basic layout – this is just to demonstrate that properties are being synchronised and loaded.

<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>
        <ListView ItemTemplate="{StaticResource PropertyItemTemplate}"
                  ItemsSource="{Binding Properties}"/>
    </Grid>
</Page>

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…..

Field Engineer Sample for Azure Mobile Services

Over on the Windows dev center there is a code sample, Field Engineer, which covers a good portion of the application scenario I painted in my previous post. I won’t be delving into the sample in too much detail but I did want to do a quick review of the solution structure so that you get an idea of what’s there and what I’ll be adding to my scenario that extends this sample.

image

The sample solution in made up of four projects and only offers a Windows application frontend (in contrast to my scenario where we want to support both native apps and a web frontend). The mobile services are in the Services project which has an accompanying Test project. The interesting thing about the test project is that it does raw httpclient calls to validate that the services work as expected, instead of using the Azure mobile service client wrapper classes. Lastly there is a Setup project which is simply a command line utility that is designed to assist in the setup of the Azure components required in order to run this sample.

I’d highly recommend downloading this sample, setup and run it (follow all the instructions otherwise it’s not likely to work), before we move onto exploring my scenario in the coming posts.

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.

When Lists aren’t Vertical or Horizontal – Going Diagonal with Windows ListView Control

The designer for a project we’re currently working on just pitched an idea where there would be a list of items that were presented along a diagonal. Back in Silverlight this probably would have been accomplished using a PathListBox but of course that doesn’t exist in the Windows 8 world. So this got me thinking …. and actually I had to reach out to UX guru Shane Morris for some inspiration. Whilst I’m not using the viewbox suggestion he had, the solution was much easier than I initially thought and essential revolves around rotating the ListView one direction and the items in the list back the other way (so they’re still horizontal).

My first pass was literally just that. A rotate transform of 27 degrees on the ListView and then a –27 degree rotate on the first item in the ItemTemplate:

<ListView>
    <ListView.RenderTransform>
        <CompositeTransform
            Rotation="27" />
    </ListView.RenderTransform>
</ListView>

<DataTemplate
    x:Key="MyItemTemplate">
    <Grid
        RenderTransformOrigin="0.5,0.5">
        <Grid.RenderTransform>
            <CompositeTransform
                Rotation="-27" />
        </Grid.RenderTransform>
        <!--     .... -->
    </Grid>
</DataTemplate>

Unfortunately this didn’t work particularly well as it ended up with too many layout issues (see below image). There was incorrect header/footer spacing but more importantly the hover effect (ie the grey background) wasn’t being rotated.

image

My next attempt involved still rotating the ListView but instead of rotating a child of the ItemTemplate I instead rotated the ListViewItemPresenter which is found by right-clicking on the ListView and selecting Edit Additional Templates, Edit Generated Item Container (ItemContainerStyle), Edit a Copy (first time only).

image

<ListViewItemPresenter .... RenderTransformOrigin="0.5,0.5">
    <ListViewItemPresenter.RenderTransform>
        <CompositeTransform Rotation="-27"/>
    </ListViewItemPresenter.RenderTransform>
</ListViewItemPresenter>

Now we’re getting closer – the hover aligns with the item as they’re both being correctly rotated. I still had issues with the positioning on the screen to ensure items scroll all the way to the edge of the screen and that all of them can still be scrolled completely into view. Firstly, I had to adjust the position of the ListView so that after rotating the trailing corner is flush with the top and bottom of the screen.

image

Doing this will prevent the first and last item being able to be scrolled into view. This can be fixed by adding a spacer into the header and footer template of the ListView.

The last issue to overcome is that the scroll bar goes off the screen at the bottom.

image

This can be fixed by tweaking the template of the scrollviewer, setting a bottom margin to lift the vertical scrollbar back onto the screen. To get to this template you have to edit the template of the ListView (not one of the additional templates), then edit the template of the ScrollViewer (which itself is part of the ListView template).

The result is that we have items that are presented, and scroll, along a diagonal line.

image

The Danger of Setting CacheMode to BitmapCache on Windows 8

This week has been full of interesting challenges as we worked to release another Windows 8 application for a client. Credit must go to the client who has set the expectation bar at an incredibly high level – I truly wish all clients had this level of respect for their brand, identity, apps, website etc. One of the challenges we came up against was with a very persistent image that refused to display correctly. By correctly I mean without any distortion, blurring, pixelation etc that happens when you incorrectly resize images. Now we only really saw this on the Surface 2 which runs at a scale factor of 140 and it was clearly evident that the image that was displayed was blurry. Following all the documentation and guidance we provided images at 100, 140 and 180 scale factors and validated that the correct image was being show by tagging each image to make them slightly unique. We also ensured that the image element was the correct size for the image and that Stretch was set to None (interesting side note – it appears that even if the element size matches the image size, if you leave Stretch to its default value of Uniform you end up with some visual distortion).

Even after doing all of that we still ended up with an image that was slightly blurry – enough that you’d have thought the image had been blown up slightly. It turns out that we had set CacheMode=BitmapCache on a parent element to ensure that when we animated the elements they would animate together. Removing the CacheMode attribute resulted in the image appearing crystal clear.

Ok, so here’s the original.

image

 

Here’s an image where the left side is taken from an element with CacheMode=BitmapCache, the right side is from an element without this attribute – spot the difference (hint, look at the edge of the spiral towards the centre)

image

 

Here’s an image where the top is taken from an element with CacheMode=BitmapCache, the bottom side is from an element without this attribute – again you should be able to see the difference.

image

 

Call out to mobile developers out there – do you care this much about your apps? If not, then you need to re-evaluate your quality bar.

Remove Tap/Mouse Down Animations on GridView and ListView for Windows 8.1

<disclaimer> The reason that the GridView and ListView have built-in animations for when a user taps or mouse-downs on an item is to provide feedback that they have indeed tapped/mouse downed on an item. I highly discourage the removal of these built-in animations as it will detract from your user experience. That said, there are times where you may need to remove these animations. For example if you nest a ListView within an item of a GridView, then, depending on what you want tappable, you’ll need to remove the animations on either the GridView or ListView.</disclaimer>

*If you’re building for Windows 8.0 then I suggest taking a look at some of the existing posts out there on how to remove storyboards from the ItemContainerStyle (eg http://stackoverflow.com/questions/10359197/windows-8-gridview-disabling-item-tap-visualization)

A lot of the discussion on the web is on how to remove various transitions from elements in Windows 8/8.1. For example setting the Transitions property to an empty TransitionsCollection. However, after setting virtually every transitions property I could find, I was still seeing the tap animation. It turns out that one solution is much simpler than I’d thought, and can be useful if you want to get rid on all the built in GridView/ListView item effects. Be warned, this will remove all those built-in effects!

Let’s walk through a simple example:

- Create a new Windows application based on the Hub App template – this will give us a GridView to work with. You can also use the Grid App if you want.

- Open the application in Blend (right-click the project and select “Open in Blend”)

- Locate a GridView to modify – we’re going to use the GridView in Section 3 of the Hub

- Right-click the GridView and select Edit Additional Templates –> Edit Generated Item Container (ItemContainerStyle) –> Edit a Copy

image

- Switch to code mode (I prefer split mode) and delete (or comment out) the GridViewItemPresenter element.

- Add an empty ContentPresenter element.

<Style x:Key="GridViewItemStyle1" TargetType="GridViewItem">
    <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
    <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="TabNavigation" Value="Local"/>
    <Setter Property="IsHoldingEnabled" Value="True"/>
    <Setter Property="Margin" Value="0,0,2,2"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="GridViewItem">
                <ContentPresenter />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

- Run the application – you’ll notice that there is no tap animation on the GridView in section 3, yet it still responds to tap or mouse click on the item (just no visible feedback).

Note: If you have a GridView or ListView that isn’t interactive you can always either disable it or set the IsHitTestVisible property to false.

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.