Building Xbox One applications with the Universal Windows Platform

Building Xbox One applications with the Universal Windows Platform

When building a Universal Windows Platform application there are times when you’ll want a different layout/functionality for a particular platform. For the most part building applications across desktop and phone, other than dealing with different screen sizes and orientation, as a developer you can rely on a similar interaction model: mouce clicks and taps equate to roughly the same interaction for most applications. However, this is not the case with the Xbox – the interaction model using either the media remote or a controller relies on a focus state moving around the screen, followed by pressing the action button to select the currently focussed item. In addition to making sure that every control has an appropriate “in focus” visual, it’s essential to make sure that the flow of focus makes sense and that the user can’t get lost in the application (eg nothing focussed, or nothing appearing to be in focus, on the screen).

The different interaction model between desktop/mobile and Xbox means that you’ll often want to present a different layout, or perhaps expose different functionality on Xbox. There are a number of ways to handle this both in XAML and in code:

1. [C#] The device family can be detected using DeviceFamily property. This returns values such as Windows.Mobile, Windows.Desktop and Windows.Xbox which can be used to define business logic that may be platforms specific. Note that the family name for Surface Hub is Windows.Team

var family = Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily

2. [XAML] The device family can be used to trigger different visual states. There are a number of state triggers that have been packaged together as a NuGet package – https://github.com/dotMorten/WindowsStateTriggers.

<VisualStateManager.VisualStateGroups>
     <VisualStateGroup x_Name=”PlatformStates”>
            <VisualState x_Name=”Xbox”>
             <VisualState.Setters>
                 <Setter Target=”textBlock.(TextBlock.Text)”
                         Value=”Running on Xbox” />
             </VisualState.Setters>
             <VisualState.StateTriggers>
                 <WindowsStateTriggers:DeviceFamilyStateTrigger DeviceFamily=”Xbox” />
             </VisualState.StateTriggers>
         </VisualState>
         … other platform states …
     </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

3. [XAML] Use different XAML files for each device family

Main.xaml  // The default XAML file

Main.DeviceFamily-Xbox.xaml  // An Xbox specific XAML file defined within the file name

/DeviceFamily-Xbox/Main.xaml // An Xbox specific XAML file defined using a folder to group together platform specific files.

Using these three different methodds might seem easy enough at first but you start to realise how frustrating it is when you want to work on a specific feature (for example navigation) but you don’t have a specific device with you (for example there’s no Xbox nearby for running the app on). To at least partial solve this problem, here are three tips that will allow you to work on your Xbox app on your desktop.

1. [C#] Instead of referencing the AnalyticsInfo class, we can add a wrapper class that allows us to override the device family whilst debugging the application. Use DeviceInfo.DeviceFamily instead of AnalyticsInfo.VersionInfo.DeviceFamily

#if DEBUG
#define DEBUG_PLATFORM_XBOX
#endif


public static class DeviceInfo
{
     public static string DeviceFamily
     {
         get
         {
#if DEBUG_PLATFORM_XBOX
             return “Windows.Xbox”;
#else
             return AnalyticsInfo.VersionInfo.DeviceFamily;
#endif
         }
     }
}

In this case the compilation constant DEBUG_PLATFORM_XBOX is used to override the actual DeviceFamily value. Note we’ve wrapped this using a #if for the DEBUG constant – this prevents the override accidentally being deployed as part of a release build.

2. [XAML] The DeviceFamilyStateTrigger (see https://github.com/dotMorten/WindowsStateTriggers/blob/master/src/WindowsStateTriggers/DeviceFamilyStateTrigger.cs) uses the DeviceFamily returned by the AnalyticsInfo class. A clone of this trigger can be made that relies on DeviceInfo.DeviceFamily (from [1]); this would activate states based on the overridden device family value.

3. [XAML] In order to debug the Xbox layout (eg MainPage.DeviceFamily-Xbox.xaml) on a desktop machine, simply rename the file to specify the Desktop device family (ie MainPage.DeviceFamily-Desktop.xaml).

Combining these three tips allows for the majority of the application to look and feel like it would when running on an Xbox. Unfortunately some of the built in components do render differently on desktop and xbox – they will always render as per the actual device family, despite attempts to override this value.

Building Media Applications for the Universal Windows Platform (UWP) using the MediaPlayerElement

Building Media Applications for the Universal Windows Platform (UWP) using the MediaPlayerElement

Over the past couple of years at Built to Roam we’ve built a number of media applications. Back when UWP was first launched, all media was played using the MediaElement, which was fairly familiar to XAML developers as it’s been the core element for any video or audio playback on Windows and Windows Phone for quite some time. Unfortunately the built in controls on the MediaElement were not easily stylable, resulting in most developers switching to using the Player Framework, which provided a host of capabilities out of the box such as closed captions, stylable regions and controls, and nice viewmodel architecture that made data binding easy.

Fast forward a year and a bit, and there’s a new player in town, literally. The MediaPlayerElement is a new control that shipped with the Anniversary update (v10.0.14393.0) and is definitely the control that you want to use if you want to do fancy things, such as a persistent video overlay where playback continues as the user continues to navigates throughout the application – this can be achieved by detaching the internal MediaPlayer from one MediaPlayerElement and attach it to another. It’s important to note that whilst the MediaPlayerElement has been around since the Anniversary update, features have been added in both the Creators update and more recently the Fall Creators update, so make sure you take a look at the documentation to make sure you are using features that align with the minimum and target versions you have set for your application.

In this post we’re going to look at the basics of using the MediaPlayerElement and how you can alter its styling. I’m going to start with a new UWP project, selecting the Creators update as the minimum version and the Fall Creators update as the target version. The MediaPlayerElement can be super simple to use – for example the following code is the simplest way to add video to a page that will automatically start playing.

<MediaPlayerElement Source=”http://sample-videos.com/video/mp4/240/big_buck_bunny_240p_30mb.mp4″  AutoPlay=”True”/>

By default the MediaPlayerElement doesn’t show any of the typical playback controls you’d expect, instead it’s just a raw video canvas that can be used to render video anywher on a page or control. In order to enable the default controls, you simply need to add the AreTransportControlsEnabled attribute set to true (I’ve removed the AutoPlay attribute as there are now going to be playback controls that can be used to start/stop video etc)

<MediaPlayerElement Source=”http://sample-videos.com/video/mp4/240/big_buck_bunny_240p_30mb.mp4″  AreTransportControlsEnabled=”True”/>

The following image shows the default controls with Progress Bar, Play/Pause, Volume, Aspect Ratio, Cast and Full screen buttons and as you’d imagine, they’re all connected to the appropriate action.

image

But what about other controls like fast forward/rewind, skip forward/backward etc. To customise what controls appear you need to override the TransportControls attribute on the MediaPlayerElement:

<MediaPlayerElement Source=”http://sample-videos.com/video/mp4/240/big_buck_bunny_240p_30mb.mp4″
                     AreTransportControlsEnabled=”True”>
    <MediaPlayerElement.TransportControls>
         <MediaTransportControls IsSkipForwardButtonVisible=”True”
                                 IsSkipBackwardEnabled=”True”
                                 IsSkipBackwardButtonVisible=”True”
                                 IsSkipForwardEnabled=”True”
                                 IsFastForwardButtonVisible=”True”
                                 IsFastForwardEnabled=”True”
                                 IsFastRewindButtonVisible=”True”
                                 IsFastRewindEnabled=”True” />
     </MediaPlayerElement.TransportControls>

</MediaPlayerElement>

Here I’ve set the TransportControls attribute to be a new instance of the MediaTransportControls class – this is actually what the default behaviour does; the difference is that I now have access to an instance that I can set attributes on. Here I’m enabling, and showing both the buttons to skip forward/backward and the buttons for fast forward/rewind. The updated layout looks like the following:

image

As you can see from the image the skip forward and backward buttons default to 30 and 10 seconds respectively. In order to adjust these you’ll need to override the behaviour that is associated with the skip forward/backward buttons, which can be done by attaching an event handler to the PositionReceived event on the MediaPlaybackCommandManager:

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


    Player.MediaPlayer.CommandManager.PositionReceived += CommandManager_PositionReceived;
}


private void CommandManager_PositionReceived(MediaPlaybackCommandManager sender, MediaPlaybackCommandManagerPositionReceivedEventArgs args)
{
     sender.MediaPlayer.PlaybackSession.Position = TimeSpan.FromMinutes(2);
     args.Handled = true;
}

In this case, I’ve named the MediaPlayerElement in the XAML (ie by adding x_Name=”Player” to the MediaPlayerElement), and then when the page has been navigated to I’m attaching the appropriate event handler. When either skip forward or backward is pressed, the position in the playback is set to the 2 minute mark and the args.Handled property is set to true, effectivey overriding the default skip behaviour. Big reminder: if you are attaching event handlers in code, make sure you detach them too (ie PositionReceived –= CommandManager_PositionReceived in the OnNavigatedFrom method).

The fast forward and fast rewind buttons will increment the playback speed up and down by doubling the rate over the range of rates supported by the content (eg –8, –4, –2, –1, 1, 2, 4, 8). The MediaTransportControls class is clever enough to detect the supported range of rates and automatically disable the fast foward/rewind buttons when the limit on the range has been reached.

Note: In working with the MediaPlayerElement, and even in preparing the sample code for this blog post, I was not able to get the fast rewind functionality to work. Fast foward appears to work but it causes the control bar to hide and show in a weird oscillating fashion. My recommendation would be to give these buttons a wide birth as this feature is severely under baked – if you want to implement something similar, perhaps with thumbnails, you should consider implementing it yourself!!! (and yes, we’ve had to do this on a project)

In this post, you’ve seen the basics of adding a MediaPlayerElment and playing some content using the built in media controls. I’ll go into more detail soon on really customising the style of your player.

Update: It seems that by setting the minimum version of the UWP application to the Fall Creators update, it appears that fast forward/rewind seems to work. I’m guessing it may have been fixed!

View Model States and Connecting them to Xamarin Forms Visual States using BuildIt

View Model States and Connecting them to Xamarin Forms Visual States using BuildIt

In my previous post on Getting Started with Visual States in Xamarin Forms using BuildIt.Forms I showed a very basic example of defining and triggering Visual States within a Xamarin Forms application. However, most applications have more complexity where each page is typically data bound to a corresponding ViewModel and it is the ViewModel which encapsulated the logic of the application.

Let me walk through working with a ViewModel using the same basic example I started in my previous post. In this case I’m going to add another panel to the page which will be displayed after the user clicks the Login button, effectively simulating the experience of showing a progress indicator whilst the application is authenticating the user.

<!– Authenticating Prompt –>
<Grid BackgroundColor=”LightPink”
         x_Name=”AuthenticatingIndicator”
         IsVisible=”false”>
     <Label Text=”Attempting to authenticate you…”
             HorizontalTextAlignment=”Center”
             VerticalOptions=”Center” />
</Grid>
<!– END Authenticating Prompt –>

In this case I’m going to add a new VisualStateGroup to define the visual states to hide and show the AuthenticatingIndicator Grid.

<vsm:VisualStateGroup Name=”AuthenticationStates”>
     <vsm:VisualState Name=”Authenticating”>
         <vsm:VisualState.Setters>
             <vsm:Setter Element=”{x:Reference AuthenticatingIndicator}”
                         Property=”IsVisible”
                         Value=”true” />
         </vsm:VisualState.Setters>
     </vsm:VisualState>
     <vsm:VisualState Name=”NotAuthenticating” />
</vsm:VisualStateGroup>

A VisualStateGroup is designed to hold mutually exclusive states. A page can have any number of VisualStateGroups, and at any given point in time the current state of the page can consist of being in one VisualState from each group. In this scenario we have broken the authenticating states away from the loading states because in theory you might want to disply both the AuthenticatingIndicator, as well as the LoadingIndicator.

The last piece of XAML that I need to update is to attach an event handler to the Clicked event of the Button:

<Button Text=”Login”
         Clicked=”LoginPressed” />

And in the code behind, define the corresponding LoginPressed method (and yes, those MVVM purist will argue that this would be better using the Command property through to the ViewModel but we’ll leave that for another post):

protected async void LoginPressed(object sender, EventArgs e)
{
}

Now that we have the XAML defined, it’s time to look at how we can drive this from our ViewModel. In my case the page I’m working with is called MainPage.xaml, so I’m going to define a class called MainViewModel in a separate .NET Standard library. I’m not going to add a reference to BuildIt.Forms to the .NET Standard library because that would bring in a reference to Xamarin Forms, which should not be referenced by the library that holds your ViewModels – they should be abstracted away from any concrete interface, which includes Xamarin Forms, even though it is itself an abstraction from the native platform interfaces. What I am going to reference is the BuildIt.States library, which is a .NET Standard library that has no reference to any specific user interface framework, making it perfect for managing states within your ViewModel.

Alongside the MainViewModel class I’m also going to define an enumeration where the names match the corresponding visual states: the enum type name has to match the VisualStateGroup name and the enum values have to match the VisualState name.

public enum AuthenticationStates
{
     Base,
     Authenticating,
     NotAuthenticating
}

The enum also has an additional value, Base, which is will be the default enum value. The name of this value is irrelevant but it’s important to have it as the first value and should not correspond to any VisualState name.

The MainViewModel class includes a StateManager property. In this case the constructor calls the extension method DefineAllStates to define states for each value of the AuthenticationState enum. The BuildIt States library has a host of great features that are worth explaining but I’ll save that topic for another post. The important thing is that each of the states for the AuthenticationState enum are defined.

public class MainViewModel
{
     public IStateManager StateManager { get; } = new StateManager();


    public MainViewModel()
     {
         StateManager.Group<AuthenticationStates>().DefineAllStates();
     }


    public async Task Login()
     {
         await StateManager.GoToState(AuthenticationStates.Authenticating);


        await Task.Delay(2000);


        await StateManager.GoToState(AuthenticationStates.NotAuthenticating);
     }
}

The Login method simply calls the GoToState method prior to calling Task.Delay, to simulate attempting to authenticate the user, and then again calling GoToState to change the state back to the NotAuthenticating state.

Now that we have our MainViewModel defined, I need to connect it to my MainPage. For real applications we work on at Built to Roam, we use frameworks such as MvvmCross to connect the View and ViewModels. However, for brevity I’m going to simply create an instance of the MainViewModel as part of the MainPage:

private MainViewModel ViewModel { get; } = new MainViewModel();

And then set the instance as the BindingContext of the page, in the constructor:

public MainPage()
{
     InitializeComponent();


    BindingContext = ViewModel;
}

Lastly, I’ll update the LoginPressed method to call the method on the MainViewModel:

protected async void LoginPressed(object sender, EventArgs e)
{
     await ViewModel.Login();
}

At this point we’re almost done: We have a ViewModel that defines the states of the application in a way that they can be tested in absence of any user interface implementation, and the View (in this case the MainPage) will invoke the Login method to trigger the state changes. The only missing component is connecting the Visual States defined on the MainPage XAML, with the states defined in the MainViewModel. This is done using the Bind method within the OnAppearing override:

await VisualStateManager.Bind(this, ViewModel.StateManager);

Now I’m ready to go – at this point the user experience is entirely defined in XAML, with all my logic, including the states, encapsulated within my ViewModel, ready to be tested.

Getting Started with Visual States in Xamarin Forms using BuildIt.Forms

Getting Started with Visual States in Xamarin Forms using BuildIt.Forms

Over the past couple of months we’ve been working on getting the BuildIt.Forms library to a point where it was stable enough to promote and talk about. With the recent release of the 2.4 update for Xamarin Forms, we’re finally able to push out a stable release.

The BuildIt.Forms library brings with it quite a few features but probably the best reason to use the library is the support it adds for defining Visual States within your Xamarin Forms application within the XAML, just like you would if you were building using XAML for UWP (or any other XAML platform such as WPF etc). We’ve tried to stay as true as possible to the syntax for Visual States used on other platforms but like all things Xamarin Forms there are some differences that you’ll need to get your head around.

Ok, before we jump in, let’s take a back step and look at what a Visual State really is, and why you’d want to use them. Let’s start with a very simple example – imagine you have a page within your application that needs to load some data and you want to provide a visual cue that something is happening. In this case I’m going to add a simple overlay with some text indicating that information is being loaded:

<!– Loading Prompt –>
<Grid BackgroundColor=”LightGray”
         x_Name=”LoadingIndicator”
         IsVisible=”false”>
     <Label Text=”Loading…”
             HorizontalTextAlignment=”Center”
             VerticalOptions=”Center” />
</Grid>
<!– END Loading Prompt –>

Note that the default IsVisible value is false, meaning that the LoadingIndicator Grid will not be visible. In the codebehind of the page I can then add code that would show the LoadingIndicator Grid, simulate loading content (ie Task.Delay), and then hide the LoadingIndicator Grid.

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


    LoadingIndicator.IsVisible = true;


    await Task.Delay(2000);


    LoadingIndicator.IsVisible = false;
}

Of course in a real application you wouldn’t do this, as there should be at least a ViewModel that would do the loading but we’ll come back to the use of ViewModels later. For the moment, it’s enough to point out that we controlling the appearance of individual elements based on the state of the page (ie showing the LoadingIndicator when the page is in the loading state). What would be great is if we could declare these states in XAML, which is where the BuildIt Forms library comes in.

I’ll add a few namespaces to the XAML for the page (mainly so I don’t forget to add them later when we talk about animations and other controls in the BuildIt Forms library):

Next, immediately inside the root tag of the page, I’ll define two visual states:

<vsm:VisualStateManager.VisualStateGroups>
     <vsm:VisualStateGroups>
         <vsm:VisualStateGroup Name=”LoadingStates”>
             <vsm:VisualState Name=”Loading“>
                 <vsm:VisualState.Setters>
                     <vsm:Setter Element=”{x:Reference LoadingIndicator}”
                                 Property=”IsVisible”
                                 Value=”true” />

                 </vsm:VisualState.Setters>
             </vsm:VisualState>
             <vsm:VisualState Name=”Loaded” />
         </vsm:VisualStateGroup>
     </vsm:VisualStateGroups>
</vsm:VisualStateManager.VisualStateGroups>

The important things to note are the names of the states: Loading and Loaded, and the use of a Setter element to adjust the IsVisible property on the LoadingIndicator element. Note that I didn’t need to set the IsVisible property to false in the Loaded state – this is because the default value of the IsVisible property on the LoadingIndicator is set to false, and the Visual State manager is clever enough to remember that when switching between states.

Now that we have visual states defined, let’s switch to the code behind and adjust the code to use the visual states:

protected override async void OnAppearing()
{
     base.OnAppearing();
    await VisualStateManager.GoToState(this, “Loading”);

    await Task.Delay(2000);
     await VisualStateManager.GoToState(this, “Loaded”);
}

It looks like we haven’t made any great improvements but here’s where the power is – let’s add some content to the screen that will be shown when the loading is complete:

<!– Login Prompt –>
<Grid x_Name=”LoginPrompt”
         IsVisible=”False”>
     <StackLayout>
         <Label Text=”Username:” />
         <Editor />
         <Label Text=”Password:” />
         <Editor />
         <Button Text=”Login” />
     </StackLayout>
</Grid>
<!– END Login Prompt –>

In the past, this would have required more code in the code behind to adjust the IsVisible property on the LoginPrompt Grid in order to show the content. With visual states, there is no need to alter the logic of the application, I just need to adjust the Loaded visual state by adding a Setter to set the IsVisible property to true.

<vsm:VisualState Name=”Loaded”>
     <vsm:VisualState.Setters>
         <vsm:Setter Element=”{x:Reference LoginPrompt}”
                     Property=”IsVisible”
                     Value=”true” />

     </vsm:VisualState.Setters>
</vsm:VisualState>

At the moment I have built an interface that provides useful feedback to the user about the loading state of the application. However, there is a rather abrupt change between the LoadingIndicator Grid and the LoginPrompt. It would be nice to be able to add animations to make the transition smoother. Again without adjusting the logic of the application I can do this by adding animations directly to the visual states. The following animation can be added after the Setters of the Loading state.

<vsm:VisualState.LeavingAnimations>
     <anim:AnimationGroup>
         <anim:AnimationGroup.PreAnimations>
             <anim:FadeAnimation Duration=”500″
                                 Opacity=”0″
                                 Element=”{x:Reference LoadingIndicator}” />
         </anim:AnimationGroup.PreAnimations>
     </anim:AnimationGroup>
</vsm:VisualState.LeavingAnimations>

In this case the animation will be run prior to (ie a PreAnimation) any state change away from (ie a LeavingAnimation) the Loading state, and will fade the LoadingIndicator Grid out to 0 Opacity over a duration of 500 milliseconds.

In this post I’ve covered the basics of creating Visual States. In my next post I’ll cover using states in a ViewModel and how you can link them to the Visual States on the page to give you a more testable application.

Hey, who moved my… Visual Studio Emulator for Android?

Hey, who moved my… Visual Studio Emulator for Android?

A while ago, in response to a common frustration from Xamarin developers, Microsoft released the Visual Studio Emulator for Android and it even made it into the Visual Studio installer:

image

As a long-serving Windows Phone developer I embraced this decision as the emulator was based on Hyper-V which meant that it played nicely with the Windows Phone emulators – I could now do cross platform development, even when I didn’t have real devices with me. Unfortunately, Microsoft have indicated that the emulator is no longer going to receive updates, so anyone wanting to dev/test on more recent builds of Android are out of luck. This was really frustrating as the emulator was both quick (relative to the out of the box emulators from Google – historically) and didn’t require another emulator sub-system (as it worked on Hyper-V).

Recently, Microsoft have actively discounted Windows Phone, making it very hard to justify any developer resources on building for Windows Phone…. it also makes me question the value proposition of UWP over WPF, but that’s a topic for a different post. The upshot is that there is no longer a reason for me to have the Windows 10 Mobile emulators installed, which means I have no need for Hyper-V, which means I can use any one of the great Android emulators out there that don’t play nice wiht Hyper-V.

What’s really cool is that Microsoft have included the Google Android Emulator in the Visual Studio installer. You need to make sure that both the Google Android Emulator and the Intel Hardware Accelerated Execution Manager are installed.

image

After installing the Google emulator you can launch your application on the emulator the same way you would to a real device – it appears in the devices dropdown. You can also access the different emulator images via the Android Emulator Manager.

image

Whilst the Android Emulator Manager is not a great looking dialog, it does allow you to customise and launch the different emulators.

image

I was so surprised when I launched the updated emulator. I was expecting an old, slow, crappy looking emulator but was surprised with an updated emulator shell with all the features that I’d come to expect from an emulator.

image

I’m a convert – Whilst I’ll still use a real device for most development work, having a good emulator is critical for those times when I don’t have a device with me. Cudos to Microsoft for firstly pushing Google to build a better developer experience and secondly making the Visual Studio installer so simple to install the emulator.

Sidenote: I did have to update one component from the Android SDK. Make sure you read the build output window in Visual Studio if you are running into issues as it pointed me to an out of date component.

Visual Studio or Blend Exception When Using XAML Designer

Visual Studio or Blend Exception When Using XAML Designer

Today we ran into a nasty issue with the XAML design experience in Visual Studio and/or Blend throwing an exception:

image

Exceptions in the designer a quite often a result of code being run by the designer that is insufficiently protected using try-catch, or has assumptions that some app startup code has run, resulting in an exception that bubbles up and causes the designer to fail. For these exceptions, I recommend checking out the post How to Debug the XAML Designer by Travis Illig, which uses another instance of Visual Studio to debug and hopefully identify the code that isn’t playing nice.

Unfortunately in our case, this didn’t help because Visual Studio (and same in Blend) was failing to resolve an assembly reference.

image

One thing that Travis point out is that there is a ShadowCache folder located at C:UsersyourusernameAppDataLocalMicrosoftVisualStudio15.0_317bf9c1DesignerShadowCache (note that you’ll need to change both “yourusername” to be your username and perhaps even the 15.0…. to reflect the current version of Visual Studio. Change VisualStudio to Blend if you’re using Blend). Within the ShadowCache folder there will be folders created for each application where you use the designer, and then a series of “bin” sub folders that will contain assemblies referenced by your application.

image

The issue we found was that we were referencing a nuget package that includes both a UWP dll as well as a .NET Standard dll. Whilst the UWP dll was being copied into a bin folder, the .NET Standard dll was not. Our fix for getting the designer to work was to copy the .NET standard dll into the same folder as the UWP dll.

Unfortunately whilst this gets the designer to work, it is a sub-optimal experience as it appears that it needs to be done every time Visual Studio is run, or when the designer process is restarted.