Nick's .NET Travels

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

Ignite Session Recordings

Earlier this month I delivered two sessions at Ignite Australia. The recording for these sessions are now available for watching

Application Development for the Universal Windows Platform
This session provides an overview of the Universal Windows Platform (UWP), a single platform that developers can target to build applications that will run across a myriad of devices. After years of progressive convergence, UWP offers a single application model, a single developer experience and a single store. The session will discuss building applications that can run on any device, whilst still being able to leverage the individual device features. It'll provide a roadmap for tools, frameworks, and guidance on building for the Universal Windows Platform.


Bare Metal Development with the Universal Windows Platform
Ignite Australia
The Universal Windows Platform offers developers a unique opportunity to build applications that run on an extensive range of devices. However, this comes the challenge of how to scale the user experience and how to adapt to different device capabilities. This session will dig deep into the use of Visual States, adaptive triggers, device family and feature detection, new binding syntax and new controls.

Changing DataContext and Compiled Data Binding in Universal Windows Platform Applications

Back in April I talked briefly about Compiled Data Binding and how it improves performance throughout your XAML application by eliminating all the reflection calls that go on in the background with traditional data binding. Recently I've been spending more time investigating the best way to structure code and design time data to ensure high quality applications. One of the easy pitfalls with the x:Bind syntax is a lack of understanding of the context of the data binding.

To start with, let's recap how traditional data binding works: Elements on the page have a DataContext, which you can think of as the object that is being data bound to. The DataBinding expression includes a Path, which determines the property on the DataContext that a particular attribute on an element is being data bound to. By default the DataContext flows down the page/usercontrol as each element inherits the DataContext from its parents. However, it is possible to override the DataContext by setting it explicitly for each element. There are plenty of sites/pages that can provide more detail on this form of data binding.

The new compiled data binding, which I'll refer to as x:Bind, tries to eliminate any use of reflection at runtime. In order to do this, the compiler generates a large quantity of code to connect the data entities and the visual elements. This means that the compiler must know Type information about both the attribute on the visual element, and the properties on the element being data bound. The starting point is that the context for x:Bind expressions on a Page is the Page itself, and similarly for a UserControl, it is the UserControl itself. If we assume that the data we want to data bind to is within our ViewModel, then we need to expose the ViewModel as a property on the Page. For example:
public MainViewModel CurrentViewModel => DataContext as MainViewModel;
and then in the XAML for the Page it can be referenced as follows:
<TextBlock Text="{x:Bind CurrentViewModel.Name, Mode=OneWay}" />
This references the Name property on the MainViewModel entity returned by the CurrentViewModel property on the page. What's not immediately obvious here is that despite indicating that the Mode is OneWay (ie it should detect changes) there is no code that notifies the data binding framework if the CurrentViewModel changes. This could happen if the DataContext changes, for example in the following code where the OnNavigatedTo method has a small latency before it sets the DataContext.
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    await Task.Delay(2000);

    DataContext = new MainViewModel();
}
In this case, the underlying DataContext is updated after 2 seconds to the new instance of the MainViewModel. This means that the CurrentViewModel value has also changed. However, there has been no attempt to notify the data binding framework, and subsequently the page, of this change. There are a number of ways to address this issue, the two I'm going to present here both rely on the Page implementing the INotifyPropertyChanged interface, exposing an event PropertyChanged, which the data binding framework will listen for.

Option 1 - Raise the PropertyChanged event manually after setting the new DataContext eg
DataContext = new MainViewModel();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CurrentViewModel"));
Option 2 - Intercept the DataContextChanged event and then raise the PropertyChanged
public MainPage()
{
    InitializeComponent();

    DataContextChanged += MainDataContextChanged;
}
private void MainDataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CurrentViewModel"));
}
Both of these options use a hardcoded property name, CurrentViewModel, which is not recommended. A last option, that might appear more complex to begin with, has the advantage of being simple, clean and less riddled with string constants. It starts with a Wrapper class, which provides a level of indirection between the Page and the ViewModel:
public class Wrapper<T>:INotifyPropertyChanged
{
    public T Entity { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;

    public Wrapper(FrameworkElement element)
    {
        element.DataContextChanged += Element_DataContextChanged;
    }

    private void Element_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
    {
        if (args.NewValue is T)
        {
            Entity = (T) args.NewValue;
        }
        else
        {
            Entity = default(T);
        }
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Entity"));
    }

    public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
And using this entity is simple as you just need to define the type of ViewModel:
public Wrapper<MainViewModel> Data => new Wrapper<MainViewModel>(this);
The only other difference is that there is an extra level of indirection in the x:Bind expression.
<TextBlock Text="{x:Bind Data.Entity.Name, Mode=OneWay}" />

Now as the DataContext on the Page changes the Wrapper class will detect the change and raise the PropertyChanged event indicating that the "Entity" has changed. Since x:Bind connects to any object in the binding path that implements INotifyPropertyChanged, it will handle this event and look for the updated Entity property, which will be the new DataContext value.

As you start to work with x:Bind, you will notice that your binding expressions are longer than you'd be used to. Don't worry about this, since the data binding itself will be orders of magnitude quicker


Certifying and Distributing Windows Store Applications to Earlier (ie Non-Supported) Versions of Windows 10 Mobile

In my previous post on Visual Studio 2015 RTM, Universal Windows Platform (UWP) Developer Tools and Debugging on a Windows Phone device I covered modifying the TargetPlatformMinVersion property in the Visual Studio project file in order to deploy your Universal Windows Platform application to a Windows 10 Mobile device. Granted that this post is probably a little too late, since the next build of Windows 10 Mobile is now out (I'm yet to install it), but it is possible to publish your application to the Store so that it can be installed on a non-developer enabled phone.

Now you'd think you'd just be able to create a Store package with the TargetPlatformMinVersion property set to the required value (in this case 10.0.10166.0 to match what I currently have on my device - see the OS Version attribute in the About screenshot below). Unfortunately this is not the case!


If you do attempt to generate a Store package you'll see an error similar to the following image - "10.0.10166.0" is not a supported value for TargetPlatformMinVersion. Please change it on the Project Property page



Ok, so step one is to revert the change to TargetPlatformMinVersion so that you can at least generate a Store package. From the Project menu in Visual Studio, select Store -> Create App Packages (if this option isn't enabled, make sure you have you UWP project selected in Solution Explorer). Follow the prompts to do a Store build - this should generate an .appx file you can work with.

What we're going to do is manually modify the generated package. From the Start menu, select the Developer Command Prompt for VS2015



Change directories to where the .appx file resides. Execute the following command, substituting you .appx filename. This will extract the contents of the .appx file into a sub-folder called "export"
makeappx unpack /nv /p myapplicationpackage.appx /d .\export
Open the AppxManifest.xml file using your text editor of choice. Locate the line that looks similar to the following and replace the MinVersion with the version number you want to target (ie 10.0.10166.0)

<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.10240.0" MaxVersionTested="10.0.10240.0" />
Close and save the updated AppxManifest.xml file. And return to the command prompt and execute the following (again feel free to replace the .appx filename)
makeappx pack /nv /d .\export /p myapplicationpackage-updatedversion.appx
And you're done - submit this package to the Store, and a couple of days later (yes, whilst certification only seems to take a couple of hours, the distribution of UWP apps is very slow at the moment, so expect to wait at least 24hours from when certification is completed) you'll be able to install your application...... of course, all of this could have been saved if you'd just updated to the latest Windows 10 Mobile build, which I'm about to do now!

Visual Studio 2015 RTM, Universal Windows Platform (UWP) Developer Tools and Debugging on a Windows Phone device

If you've upgraded to Visual Studio 2015 RTM with the associated Universal Windows Platform tools, you may have realised that you can't deploy apps to a real Windows Phone that's running the current Windows Insider Preview build for Windows Phone. This is because the version of the SDK, which has a version/minversion of 10.0.10240.0, is higher than what's currently available for the phone. For application development and testing this means using the emulators that ship with the SDK.

Of course, this isn't a great story as lots of developers much prefer debugging on a real device. In fact there are scenarios where a real device is the only way to test some scenarios. I came across the following post that provides a temporary, NON-SUPPORTED solution.

https://social.msdn.microsoft.com/Forums/en-US/46889785-07bd-4e10-9134-e8fa429b1486/uwp-is-it-possible-to-deploy-a-uwp-app-build-in-vs2015rtm-to-windows-phone-running-10010166?forum=wpdevelop

The solution rests on manually changing the TargetPlatformMinVersion property in the UWP project file to be the same as what's running on the phone (in my case 10.0.10166.0). Don't change the TargetPlatformVersion property - doing this will mean that you won't be able to open the project in Visual Studio since that version isn't supported with the SDK.

WARNING: Whilst making this change may mean that you can debug your application on a real device, just be aware that it may through weird errors if you happen to try to access an API that has actually changed between 166 and 240 builds. Your code is still going to be built against the 10.0.10240.0 API set, you're just lying in the package manifest, claiming that your app will run on a previous version.

As you can imagine this has been designed with future versions in mind. If you open the project properties dialog for the UWP application you'll see that on the Application tab there is a Targeting section. In the current SDK there is only one option for the target version and min version. Going forward you can imagine that a future SDK will allow for selection of 10.0.10240.0 (the current version) and a future version (where APIs may have evolved).

 

Application Development Using States and Transitions

Having worked with each of the different XAML based technologies Microsoft has released (WPF, SL, WP, Win, UWP...), I've long been a proponent of the use of visual states. Jerry Nixon discusses using visual states to build Windows 8.1 application. I've written articles that talk about using visual states for changing page layout to reflect states within a view model. Let me talk briefly about why I favour visual states and why the visibility property is often misused.... then we'll get onto discussing using states for building applications.

Developers new to working with XAML discover that they can hide/show items on the page by data binding a Boolean property on the view model (this assumes they're using mvvm/data binding) with the visibility property on an element. This of course requires a Boolean to visibility converter. It works nicely and assuming the developer has implemented INotifyPropertyChanged and is raising the PropertyChanged event correctly, the elements on the page will hide/show as required.

Whilst there isn't anything wrong with this approach, it makes it difficult to design the layout in Blend. In order to hide/show elements, you have to modify the design time data (assuming you've bothered to create design time data). The alternative is to use visual states to describe how the page looks for each state. Blend for Visual Studio includes a States window which allows for one or more states to be invoked, making it easy to create, view and edit visual states, at design time!


Ok, time to move on an talk more about using states as a foundation for application development. Unfortunately we can't jump there yet as we need to first look at different levels of how an application hangs together. Rather than get into a discussion on the similarities and differences between application platforms, let's just look at the Windows platform (this should apply to Windows Phone, Windows 8.x and Windows 10):

- An application typically has a frame, within which it navigates between pages

- A page can be made up of any number of visual state groups, and can have a single visual state selected at any time from each visual state group. Animations can be run as part of transitioning between states.

- Controls (including Usercontrols) can contain their own visual states that determine how they look under various conditions (pressed, checked, selected etc).

What's interesting about this is that the navigation between pages is actually the odd one out. Most application developers devote a large portion of the application development process to ensuring the navigation between pages is correct. They spend very little time working through the visual states of pages (often hacking away at hiding/showing elements on the screen). So, what happens if we make the assumption that each one of these scenarios can be expressed as a series of states?

As a starting point, we'd need a definition of a state. In the past, to keep the states of a view model separated from the visual states on a page I typically create an enumeration which has values that have the same names as the visual states. The view model then keeps track of which state is currently selected. Changing the current state raised a StateChanged event, which is handled by the page where it invokes the GoToState method on the VisualStateManager. My basic definition of a state will be an extension of this where the IStateDefinition is based on an enumeration type (well, at least a struct):

public interface IStateDefinition<TState> where TState : struct
{
    TState State { get; }
}

with a simple implementation:

public class BaseStateDefinition<TState> : IStateDefinition<TState>
    where TState : struct
{
    public TState State { get; set; }
}

And we can then define an interface for an entity which maintains current state, allows for a change in state and raise an event when the state changes:

public interface IStateManager<TState> : INotifyPropertyChanged
    where TState : struct
{
    event EventHandler<StateEventArgs<TState>> StateChanged;

    TState CurrentState { get; }

    IDictionary<TState, IStateDefinition<TState>> States { get; }

    Task<bool> ChangeTo(TState newState, bool useTransition = true);
}

The first instinct would be for the view model to implement this interface, but this won't work since the view model would have to implement the interface for each state group that it needs to track. This means we need an implementation of this interface that tracks current state for each state group:

public class BaseStateManager<TState> :
    NotifyBase, IStateManager<TState>
    where TState : struct
{
    public event EventHandler<StateEventArgs<TState>> StateChanged;

    public TState CurrentState { get; private set; }

    public IDictionary<TState, IStateDefinition<TState>> States { get; set; }


    public async Task<bool> ChangeTo(TState newState, bool useTransitions = true)
    {
        var current = CurrentState;
        if (current.Equals(newState)) return true;

        CurrentState = newState;

        try
        {
            StateChanged?.Invoke(this, new StateEventArgs<TState>(newState, useTransitions));
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
            // Ignore any errors caused by the event being raised, as
            // the state change has still occurred
        }
        return true;
    }
}

We'll use this as the basis from which we can track states at an application, page and control level.







Launching Windows Store Applications from Code in Windows 10

On Windows 8/8.1 after installing an application from the Windows Store it was possible to interrogate the registry and find the AppUserModelId which could then be used to launch the application. This process is described in more detail here - http://www.codeproject.com/Articles/542316/Run-Windows-Store-Apps-From-Desktop.

There are a couple of ways to launch the application using the AppUserModelId:

- The first (as the link suggests) is to use the launcher utility that comes with the SDK eg:
C:\Program Files (x86)\Windows Kits\8.0\App Certification Kit\Microsoft.Windows.SoftwareLogo.AppxLauncher.exe “AppUserModelId

- The other way is to use the ApplicationActivationManager (https://msdn.microsoft.com/en-us/library/windows/desktop/hh706902(v=vs.85).aspx) which can be used as follows:

uint pid;
var mgr = new ApplicationActivationManager();
mgr.ActivateApplication("[AppUserModelId]", null, ActivateOptions.None, out pid);

This technique relies on getting the AppUserModelId from the following Registry:

HKEY_CURRENT_USER\Software\Classes\ActivatableClasses\Package\**PackageFullName**\Server

The installation process for Store applications on Windows 10 doesn't create this Registry key, which means we need another way to determine the AppUserModelId. I haven't found a definitive way to do this but I did manage to find a way which seems to work. Essentially you need to append "!App" to the package family name of your application (not the package full name).

If you haven't played around with the powershell commands for installing and querying installed packages, it's worth taking a look. For example to get a list of all packages for a particular publisher you can issue the following powershell command:

get-appxpackage -publisher "OID.0.9.2342.19200300.100.1.1=6434210, CN=Built to Roam Pty Ltd, OU=Built to Roam Pty Ltd"

This will return a listing for each application such as the following:

Which, as you can see contains the PackageFamilyName - add "!App" and you have a string that should work as the AppUserModelId, allowing you to launch the application from code.



Visual Studio 2015 RTM and the case of the missing Microsoft Advertising SDK for Windows 8.1

I just got around to upgrading to VS2015 RTM having run the RC since it was available (just as an aside VS2015 has been the only version of Visual Studio that I've been running for quite some time now). And as Murphy's law goes, the first project I open doesn't build and run - OMG what pain do I now need to endure?

It appears that someone has made the decision to remove the Windows 8.1 Advertising SDK (perhaps due to the recent sale of MS advertising assets), which means my Windows 8.1 application is now missing a reference.  According to the Ads in Apps website (http://adsinapps.microsoft.com/en-US/sdk) the SDK is installed in VS2013 update 2 or later (clearly not the case)

Luckily, a bit of searching revealed the SDK available via Visual Studio Gallery at https://visualstudiogallery.msdn.microsoft.com/3d3fa204-0641-4317-ab2c-50092f732edb

Windows Phone 8.1, Microsoft Lumia 640XL and the case of the Virtual Hardware Buttons

The Microsoft Lumia 640 and 640XL were one of the first Windows Phone devices to take advantage of the move to on-screen hardware buttons. Rather than the traditional hardware buttons for Back, Start and Search, these devices have software rendered buttons (note that there were previous devices that had the buttons as part of the same glass as the reset of the screen but this isn't the same as having them rendered in software). There were some that didn't like this move (eg http://www.7tutorials.com/reviewing-microsoft-lumia-640-xl-good-smartphone-business-users) but an nice effect of them being software is that they can be dismissed off the screen. This means that the buttons can be swiped away, leaving more screen available for applications.

The unfortunately thing about this is that because this feature shipped as an update to Windows Phone 8.1 there isn't good support for detecting when the available screen size changes, often leaving applications either with controls rendered under the buttons, or with empty screen space under the content of the application (where the buttons used to reside).

Side note: Rudy Huyn in his post, "How to test my app on phone with navigation bar and why it matters," covers how to use the Windows Phone emulator to test applications for this behaviour.

I spent a bit of time this afternoon trying to work out a workable solution to this. The result was a bit hit and miss but the following seems to work:

In order to take advantage of the full screen I added the following lines to the end of the OnLaunched method in the App.xaml.cs file:

var applicationView = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView();
applicationView.SetDesiredBoundsMode(Windows.UI.ViewManagement.ApplicationViewBoundsMode.UseCoreWindow);

The UX of the screen is very basic - it has a background color so that you can see where the page is being rendered and a textbox at the bottom of the screen so that you can see whether an element has been hidden. Note also that the VerticalAlignment of the page is set to Top. This might seem weird but if you don't, as you adjust the Height of the page in accordance with the visible bounds, you'll see the page rendered in the middle of the screen, which is not what you want.

<Page x:Class="AppBarTest.MainPage"
      xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml"
      VerticalAlignment="Top">
    <Page.BottomAppBar>
        <CommandBar>
            <AppBarButton Icon="Accept"
                          Label="appbarbutton" />
            <AppBarButton Icon="Cancel"
                          Label="appbarbutton" />
        </CommandBar>
    </Page.BottomAppBar>

    <Grid Background="LightBlue">
        <TextBox Text="Testing"
                 VerticalAlignment="Bottom"
                 Margin="0" />
    </Grid>
</Page>

The code for this page is where all the hacking happens - essentially it looks to determine how tall the page should be based on the space occluded by the status bar and the input pane. The trick is to make sure this is called anytime something adjusts the visible bounds available to the app.

public sealed partial class MainPage
{
    public MainPage()
    {
        InitializeComponent();
           
        var appView = ApplicationView.GetForCurrentView();
        appView.VisibleBoundsChanged += VisibleBoundsChanged;
    }

    private void VisibleBoundsChanged(ApplicationView sender, object args)
    {
        ResizeMe();
    }

    private void ResizeMe()
    {
        var statusBar = StatusBar.GetForCurrentView();

        var appView = ApplicationView.GetForCurrentView();
        var input = InputPane.GetForCurrentView();
        var newHeight = appView.VisibleBounds.Height + (statusBar?.OccludedRect.Height) ??
                                0 + (input?.OccludedRect.Height) ?? 0;
        if ((input?.OccludedRect.Height ?? 0) <= 0 || newHeight <
this.Height)
        {
            this.Height = newHeight;
        }
    }

Update: You should also attach an event handler to the Got and Lost focus on the TextBox and invoke ResizeMe otherwise there are some scenarios where the TextBox ends up under the virtual buttons

Compiled DataBinding in Windows Universal Applications (UAP)

This question on stackoverflow which references the Windows 10 jumpstart videos (http://www.microsoftvirtualacademy.com/training-courses/a-developers-guide-to-windows-10-preview?prid=ch9courselink) raises the topic of compiled data bindings. Currently there is no documentation about this feature and I doubt that we’ll see much out of Microsoft prior to Build. However, the x:Bind syntax is available in the insiders preview of the Windows 10 SDK so I figured I’d explore it a little.

Let’s start with a simple expression:

<TextBlock Text="{x:Bind}" />

When you add this to a page and run it, you’ll see the Type name of the page displayed in the TextBlock (eg CompiledDataBindingSample.MainPage). In order to examine this further let’s create a simple custom control with a dependency property and corresponding change handler:

public class CustomControl : Control
{
    Windows.UI.Xaml.Markup.IComponentConnector x;

    public string Test
    {
        get { return (string)GetValue(TestProperty); }
        set { SetValue(TestProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Test.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TestProperty =
        DependencyProperty.Register("Test", typeof(string), typeof(CustomControl), new PropertyMetadata(null, TestChanged));

    private static void TestChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var newData = (d as CustomControl).Test;
        Debug.WriteLine(newData.GetType().Name);
    }
}

Now let’s add an instance of this control onto the page and data bind to the Test property:

<local:CustomControl Test="{x:Bind}" />

When this is run we can set a breakpoint on the Debug.WriteLine and we can examine the newData object. What’s interesting is that the newData object is the instance of the page that is hosting the control. In other words, the value being passed into the binding expression is the page itself (in this case an instance of MainPage) – this explains why in the TextBlock showed the type name, as this is the default ToString() value. This is interesting in itself as it means that the context for data binding with x:Bind is the page itself, in contrast to the default DataContext of null when using Binding.

The other thing that’s worth looking at is the Call Stack window. The first two frames make sense, being the set and change handler for the dependency property but then it gets interesting as it references a class called MainPage_obj1_Bindings with methods such as SetValue_obj3_Test, Update_, InitializeCore, Initialize etc.

image

At this point I think it’s time to go take a look at what’s been generated when the application was compiled. In this case we’ll use ILSpy to get a list of the classes that make up the application. As you can see from this screenshot MainPage has a couple of nested types, MainPage.IMainPage_Bindings and MainPAge.MainPage_obj1_Bindings, along with a field/property combination that exposes an instance of MainPage.IMainPage_Bindings. There is also an additional method, Connect, which has been injected into the MainPage during compilation.

image

A further examination of the base types collection shows that in addition to inheriting from Page, MainPage implements Windows.UI.Xaml.Markup.IComponentConnector, which no surprises defines a method, Connect(int, object). So, what does this method do? Using ILSpy to inspect the contents on the Connect method we can see that it generates an instance of the MainPage_obj1_Bindings class and associates it with the elements on the page (in this case the TextBlock and the CustomControl). Clearly this method is going to be invoked during the initialization phase of a page.

Now, let’s turn our attention to the MainPage_obj1_Bindings class. It would appear that this class has instance variables for each of the elements that has an x:Bind expression. In this case it has variables obj2 (TextBlock) and obj3 (CustomControl). It also has some generated methods such as SetValue_obj2_Text which explicitly sets the Text value on the TextBlock. This makes me think back to a time before data binding where properties had to be explicitly set in code. Whilst data binding has been an effective way for developers to declaratively wire up properties to underlying data, it did add a significant overhead and subsequent performance hit – for large data sets this can be quite significant and hard to work around. By the looks of these generated methods, it would appear that by converting the data binding expression into compiled code, some of the performance overhead of data binding can be overcome.

Ok, so now that we’ve taken a bit of a look at some of the aspects of compiled data binding, let’s go back to XAML and take a look at extending the binding expression to include a path. In most cases we’ll want to bind attributes on the visual elements to properties on a view model. The question is how to do this using x:Bind. Let’s see what happens when we add ViewModel to the binding expression:

<TextBlock Text="{x:Bind ViewModel}" />

Normally, if you add a path to a binding expression that isn’t valid it will compile and run without any issues. In this case, there is no ViewModel property on the MainPage, so when the application is compiled the following build error is generated:

Invalid binding expression 'MyProperty' : Unrecognized property 'MyProperty' at offset '0'

Let’s add a ViewModel property to the MainPage:

public MainViewModel ViewModel { get; set; }

public MainPage()
{
    ViewModel = new MainViewModel();
    this.InitializeComponent();

}

The MainViewModel class exposes a property, HelloText, and implements the INotifyPropertyChanged interface. Of course, normally this would be implemented in a base class with an OnPropertyChanged or RaisePropertyChanged helper method.

public class MainViewModel : INotifyPropertyChanged
{
    private string hello = “Hello World”;
    public string HelloText
    {
        get { return hello; }
        set
        {
            hello = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("HelloText"));
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

In order to reference the HelloText property, we’ll extend the binding expression:

<TextBlock Text="{x:Bind ViewModel.HelloText}" />

Running this appears to work with the text “Hello World” appearing in the TextBlock. Let’s try updating the HelloText. A simple Run method will update the HelloText property every second.

public async void Run()
{
    var i = 0;
    while (true)
    {
        await Task.Delay(1000);
        HelloText = "Hello " + i++;
    }
}

Unfortunately this doesn’t seem to do anything, with the TextBlock not updating. This behaviour is consistent of a OneTime data binding. Let’s add Mode=OneWay to the binding expression.

<TextBlock Text="{x:Bind ViewModel.HelloText, Mode=OneWay}" />

Now the TextBlock updates every second as we’d expect. So it appears that unlike a traditional Binding, the x:Bind expression defaults to a OneTime mode, instead of OneWay. ILSpy also indicates that the MainPage_obj_Bindings has a sub-class, MainPage_obj1_Listener, which is designed to hook up to the INotifyPropertyChanged.PropertyChanged event. This again will help ensure updates are passed to the appropriate elements without any need for Reflection based calls.

Microsoft Continues the Integration Between Blend and Visual Studio

Years after Microsoft attempted to lure designers into the world of app development by giving them a tool where they could assist with the designing of applications, it appears that Microsoft still recognises that design and development, whilst different roles, go hand in hand as part of the development process. In Visual Studio 2015 the integration between Visual Studio and Blend for Visual Studio becomes even more apparent. The changes range from the simple things, like the link to open Blend from within Visual Studio being renamed to “Design in Blend,” through to intellisense in the XAML editor in Blend and better alignment of the various tool windows.

image

Windows 10 Jumpstart Training

Whenever I try to locate the jumpstart training for the Windows 10 Developer Preview tools it always seems to take longer than expected. Anyhow, I thought I’d re-post the direct links to each of the sessions here so that at least I can find them easily next time:

Developer's Guide to Windows 10 Preview- (01) Getting Started

Developer's Guide to Windows 10 Preview- (02) Start Simple- Hello World

Developer's Guide to Windows 10 Preview- (03) Migrating 8.1 Apps to Windows 10

Developer's Guide to Windows 10 Preview- (04) Extension SDKs

Developer's Guide to Windows 10 Preview- (05) SplitView Control

Developer's Guide to Windows 10 Preview- (06) Maps

Developer's Guide to Windows 10 Preview- (07) Pen & Ink

Developer's Guide to Windows 10 Preview- (08) RelativePanel Control

Developer's Guide to Windows 10 Preview- (09) Adaptive Triggers

Developer's Guide to Windows 10 Preview- (10) App-to-App Communication

Developer's Guide to Windows 10 Preview- (11) New XAML Controls and XAML Transform 3D

Developer's Guide to Windows 10 Preview- (12) App Services

Developer's Guide to Windows 10 Preview- (13) Action Center

Developer's Guide to Windows 10 Preview- (14) Evolving the Web Platform

Unable to Activate Windows Store App

I was running up one of our Windows 10 projects today and I encountered a somewhat cryptic error stating that Visual Studio was “Unable to activate Windows Store app…. The … process started, but the activation request failed with the error ‘The app didn’t start’”.

image

I figured there would be more information in the event log but this was not the case, with only this same message appearing there. Luckily it turns out that this issue isn’t specific to Windows 10 applications, and it was in fact this post that clued me on to removing the somewhat unnecessary app.config file that was still in my solution structure. Removing this file worked an absolute treat, although I can’t seem to work out why it fails since Visual Studio does sometimes warn about multiple versions of an assembly being referenced.

Package Manifest for Windows 10

As the tools for Windows 10 applications are still in preview there are some limitations and some features that aren’t quite ready yet. One of these is the designer for the package.manifest file, so the question is how do you know what elements can go in the manifest file. The manifest file is validated using a number of .xsd files that exist in the folder C:\Program Files (x86)\Windows Kits\8.2\Include\10.0.10030.0\winrt

image

These include the various namespaces defined at the beginning of the package.manifest file:

xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap=http://schemas.microsoft.com/appx/manifest/uap/windows10

Disabling the Pinch-Zoom behaviour of the WebBrowser control on Windows Phone

This is an issue that seems to keep coming back to haunt us on various projects where we have to embed web content within a Windows Phone application. One of the best solutions is to modify the CSS of the page being displayed to disable the touch behaviour using the –ms-touch-action (noted that whilst in IE11+ the recommendation is to use the touch-action property but for WP the vendor prefix is still required).

One of the team that I work with came across a post by Colin Eberhardt that handles some of the manipulation events in the visual tree surrounding the actual web content, thereby disabling the pinch-to-zoom behaviour. This technique makes use of Linq to XAML/Visual Tree which is also worth a read

Fix Login Failures to Azure Mobile Services with Enhanced Users Features for Javascript Backends

One of the applications that we’ve been working on that leverages the older javascript backend version of Azure Mobile services was seeing some cases where users couldn’t login. For a while we put it down to incidental issues with our application but we then detected a pattern where it was related to Microsoft Accounts that belonged to one of the domains associated with outlook.com (eg live.com, outlook.com, outlook.com.au, hotmail.com). I don’t know exactly which domains it does affect, nor whether it was all email addresses on those domains. However, what I do know is that in order to fix the issue we had to follow the instructions that Carlos had posted a while ago on the Enhanced Users Feature. We hadn’t done this previously as I wasn’t confident that it wouldn’t break our production application but it turns out the only change we needed to do, as per his instructions, was change to use the asynchronous getIdentities method (which is also an update we were supposed to do a while ago!).

Navigation Flow for Real Estate Inspector Application for Windows Phone

In building out the pages for the Real Estate Inspector application the first step is to think through the core pages that make up the application. The following navigation flow diagram illustrates the four pages that would make up the phone application. In this case each of the four nodes represent pages or views that you’d expect to see within the application.

image

However, if we consider what might happen on a slate/tablet/desktop experience, not all of these nodes has to be a dedicated page. For example, the Login might be a popup/modal style dialog that appears across the centre of the screen. In fact, with Windows, this is exactly how the Web Authentication Broker appears. There may also be other non-core views that are not represented on here which will features as pages/views on phone but as nested views or modal style dialogs on the larger screen. For example viewing a photo may be a full screen, separate page, experience on phone. On larger devices it may be that this is again a popup/modal style interface.

One thing that can be noted from this diagram is that the Login can be accessed from any of the nodes. Whilst the initial experience will be to navigate to Login from the Home page on first run, at any point there after, if synchronisation fails due to an authentication issue, it’s important that the user is prompted to authenticate immediately to ensure they can continue to operate. This doesn’t need to be a blocking operation as it may be that the user needs to continue to work, despite authentication failing. It is however, important that some rules are in place to ensure the user does update their authentication information (ie enter correct password) within a nominated period for security reasons. After all, there is the scenario where the user no longer works for the organisation in which case their account should both be locked (ie can’t authenticate) and access should be prevented to the application.

Data Synchronization and Sqlite Data Model For Multi-User Scenarios

Most consumer application are built to either run anonymously (ie not captured information about who the user is) or they are designed with a single user in mind (think the Facebook application – whilst you can log out, typically to stay logged in, even across multiple sessions of running the application). Enterprise or Line of Business applications, particularly on slate/tablet devices are often multi-tenanted with users picking up the nearest device to them, running the app, signing in and getting to work. With this in mind the real estate inspector application has been architected so far to allow for login and switching between users. However, the local caching has been to a single Sqlite database which resides in the users application data folder. If users switch Windows profile then there isn’t an issue but this doesn’t work for devices where there isn’t a notion of user specific data folders. In this case all users will access the same database, which will result in synchronization issues or users seeing data that isn’t assigned to them.

A simple solution would be to simply create a different database for each user. However, if there is data that is common across all users (Eg property types) this will be synchronized into each database. An alternatively approach is to have a common or master database which is used to synchronise data that is common across all users, then to have individual user databases that just contain the user specific data.

Source Code for Real Estate Inspector Sample on GitHub

I’ve got around to publishing the current source code pieces to GitHub. It’s currently very hotch-potch as I’ve been focussing on demonstrating/fleshing out a lot of the concepts for my blog posts. Over the coming weeks I’ll be extending out the actual functionality and will periodically update the code on GitHub. For now, it’s a good place to pick through the various code I’ve been talking about over the last couple of months

Using a Refresh Token to Renew an Expired Access Token for Azure Active Directory

Currently my application attempts to acquire the access token silently which equates to looking to see if there is a current (ie not expired) token in the token cache. However, tokens don’t live for very long, so it’s quite likely that a token won’t be found. This unfortunately leads to a poor user experience as the user will quite often be prompted to sign in. There is an alternative, which is to use the refresh token, returned as part of initially acquiring the access token, to silently request a new access token. This of course is on the assumption that the refresh token hasn’t expired.

Here is a quick summary, as at the time of writing, of the different tokens and their expiry rules (a good explanation here):

  • Azure AD access tokens expire in 1 hour (see the expires_on attribute that is returned when acquiring an access token).
  • Refresh tokens expires in 14 days (see the refresh_token_expires_in attribute that is returned when acquiring an access token).
  • Access tokens can be refreshed using the refresh-token for a maximum period of time of 90 days, from the date that the access token was acquired by prompting the user.

The authentication logic can be amended to retrieve the list of refresh tokens, attempt to acquire token silently, followed by an attempt to acquire token via the refresh token. Failing that the user would be prompted to sign in.

var authContext = new AuthenticationContext(Configuration.Current.ADAuthority);

var tokens = authContext.Tokens();
var existing = (from t in tokens
                where t.ClientId == Configuration.Current.ADNativeClientApplicationClientId &&
                        t.Resource == Configuration.Current.MobileServiceAppIdUri
                select t).FirstOrDefault();
if (existing != null)
{
    try
    {
        var res = await authContext.AcquireTokenSilentAsync(
            Configuration.Current.MobileServiceAppIdUri,
            Configuration.Current.ADNativeClientApplicationClientId);
        if (res != null && !string.IsNullOrWhiteSpace(res.AccessToken))
        {
            return res.AccessToken;
        }
    }
    catch (Exception saex)
    {
        Debug.WriteLine(saex);
    }

    try
    {
        var res = await
            authContext.AcquireTokenByRefreshTokenAsync(existing.RefreshToken,
                Configuration.Current.ADNativeClientApplicationClientId);
        if (res != null && !string.IsNullOrWhiteSpace(res.AccessToken))
        {
            return res.AccessToken;
        }
    }
    catch (Exception saex)
    {
        Debug.WriteLine(saex);
    }

}