Databinding Conversions Using Functions in UWP XAML Apps

When using compiled data bindings using the x:Bind syntax in UWP apps, as an alternative to using an IValueConverter, a function can instead be defined. This means that whenever a value needs converting from the source object to the XAML property, the function will be called rather than an IValueConverter. This functionality is available from the Windows 10 Anniversary update so your UWP app in Visual Studio will need to be targeting version 14393 or later.

As an example, suppose there was already some existing code that maps whether a customer is considered high risk to a color, e.g. high risk customers should be shown in red. One way to accomplish this when databinding in the UI is to create an IValueConverter and then call into the existing code to do the conversion. Another option is to simply call the function from the XAML databinding – this reduces the need to write the additional IValueConverter implementation.

Take the following XAML:

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    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}">
        <StackPanel>
            <TextBlock Text="{x:Bind CustomerName}" FontSize="36"></TextBlock>
            <TextBlock Text="{x:Bind IsHighRisk}" FontSize="36"></TextBlock>
        </StackPanel>
    </Grid>
</Page>

In the preceding XAML, we want the IsHighRisk  TextBlock to appear in red if the customer is a high risk customer.

Imagine we already had some code to do this as follows:

using Windows.UI;
using Windows.UI.Xaml.Media;

namespace App1
{
    static class RiskColorMapper
    {
        public static Brush ToColor(bool isHighRisk)
            => isHighRisk ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.Olive);
    }
}

We can now use the x:Bind syntax to call into this function and bind the foreground color to the boolean value of the IsHighRisk property as the following modified XAML demonstrates:

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    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}">
        <StackPanel>
            <TextBlock Text="{x:Bind CustomerName}" FontSize="36"></TextBlock>
            <TextBlock Text="{x:Bind IsHighRisk}" FontSize="36" Foreground="{x:Bind local:RiskColorMapper.ToColor(IsHighRisk)}"></TextBlock>
        </StackPanel>
    </Grid>
</Page>

Now if we run the app with IsHighRisk set to false the text foreground is olive, if IsHighRisk is true the text will be red as the following screenshots show:

UWP data binding to function screenshot

UWP data binding to function screenshot

If the binding is TwoWay, the BindBack binding property can also be added that points to a function to do the reverse conversion.

For more info check out MSDN.

SHARE:

Playing and Processing Audio in UWP Apps with Audio Graphs

UWP apps can take advantage of the Audio Graph API. This allows the creation of audio nodes into an audio signal processing pipeline/graph.

Audio flows from one node to the next with each node performing a defined task and optionally using any applied effects. One of the simplest graphs is to use an AudioFileInputNode to read audio data from a file and an AudioDeviceOutputNode to write it out to the device’s soundcard/headphones.

diagram of simple uwp audio graph nodes connected together

There are a number of nodes provided out of the box including the AudioDeviceInputNode to read audio from the microphone; the AudioFileOutputNode to output audio to a file, and even AudioFrameInputNode and AudioFrameOutputNode to perform custom audio sample processing as part of the graph. As the name suggests, a graph can branch out and recombine as required; for example sending input to 2 other nodes in parallel and then recombining them into a single output node.

Audio effects can also be added to nodes, such as the pre-supplied echo, reverb, EQ, and limiter. Custom effects can also be written and plugged into the graph by implementing the IAudioEffectDefinition interface.

Getting Started

To start, create an empty UWP Windows 10 project and add the following XAML to the MainPage:

<Page
    x:Class="AudioGraphDemo.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}">
        <Button Name="Play" Click="Play_OnClick">Play</Button>
    </Grid>
</Page>

In the code behind start by adding the following usings:

using System;
using System.Threading.Tasks;
using Windows.Media.Audio;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

And the following fields to hold the audio graph itself and the 2 nodes:

AudioFileInputNode _fileInputNode;
AudioGraph _graph;
AudioDeviceOutputNode _deviceOutputNode;

Next create the button click event handler:

private async void Play_OnClick(object sender, RoutedEventArgs e)
{
    await CreateGraph();
    await CreateDefaultDeviceOutputNode();
    await CreateFileInputNode();

    AddReverb();

    ConnectNodes();

    _graph.Start();
}

We can now add the following methods:

/// <summary>
/// Create an audio graph that can contain nodes
/// </summary>       
private async Task CreateGraph()
{
    // Specify settings for graph, the AudioRenderCategory helps to optimize audio processing
    AudioGraphSettings settings = new AudioGraphSettings(Windows.Media.Render.AudioRenderCategory.Media);

    CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);

    if (result.Status != AudioGraphCreationStatus.Success)
    {
        throw new Exception(result.Status.ToString());
    }

    _graph = result.Graph;
}

/// <summary>
/// Create a node to output audio data to the default audio device (e.g. soundcard)
/// </summary>
private async Task CreateDefaultDeviceOutputNode()
{
    CreateAudioDeviceOutputNodeResult result = await _graph.CreateDeviceOutputNodeAsync();

    if (result.Status != AudioDeviceNodeCreationStatus.Success)
    {
        throw new Exception(result.Status.ToString());
    }

    _deviceOutputNode = result.DeviceOutputNode;
}

/// <summary>
/// Ask user to pick a file and use the chosen file to create an AudioFileInputNode
/// </summary>
private async Task CreateFileInputNode()
{
    FileOpenPicker filePicker = new FileOpenPicker
    {
        SuggestedStartLocation = PickerLocationId.MusicLibrary,
        FileTypeFilter = {".mp3", ".wav"}
    };

    StorageFile file = await filePicker.PickSingleFileAsync();

    // file null check code omitted

    CreateAudioFileInputNodeResult result = await _graph.CreateFileInputNodeAsync(file);

    if (result.Status != AudioFileNodeCreationStatus.Success)
    {
        throw new Exception(result.Status.ToString());
    }

    _fileInputNode = result.FileInputNode;
}

/// <summary>
/// Create an instance of the pre-supplied reverb effect and add it to the output node
/// </summary>
private void AddReverb()
{
    ReverbEffectDefinition reverbEffect = new ReverbEffectDefinition(_graph)
    {
        DecayTime = 1
    };

    _deviceOutputNode.EffectDefinitions.Add(reverbEffect);
}

/// <summary>
/// Connect all the nodes together to form the graph, in this case we only have 2 nodes
/// </summary>
private void ConnectNodes()
{
    _fileInputNode.AddOutgoingConnection(_deviceOutputNode);
}

Now when the app is executed, the user can choose a file, this file is then played with added reverb. Check out the MSDN documentation for more info.

If you want to fill in the gaps in your C# knowledge be sure to check out my C# Tips and Traps training course from Pluralsight – get started with a free trial.

SHARE:

Your First Xbox One UWP App

image

There’s been a number of almost-goosebump-inspiring moments during my .NET dev experience such as the first time I saw my code running on a Windows Phone 7. Another one of these moments was seeing my code running on my Xbox One for the first time.

(Note: this post describes pre-release technology)

It is now possible to take your regular Fallout 4 playing retail Xbox One and turn it into a development machine. This allows the running of Universal Windows Platform (UWP) apps. At the time of writing this is in preview/pre-release status with a final release expected later this year.

There’s a great set of documentation on MSDN that describes the following steps in detail. I’d recommend reading through them all before starting the process as there’s a number of warnings that should be observed before starting. For example “some popular games and apps will not work as expected, and you may experience occasional crashes and data loss. If you leave the developer preview, your console will factory reset and you will have to reinstall all of your games, apps, and content” [MSDN].

Also be aware that, to enable Xbox UWP app development in Visual Studio, the Windows 10 SDK preview build 14295 needs to be installed: “Installing this preview SDK on your PC will prevent you from submitting apps to the store built on this PC, so don’t do this on your production development PC” [MSDN]. I created a new Hyper-V virtual machine so as not to disturb my base machine.

The documentation recommends using a hardwired network connection rather than wireless for better dev performance, I used wireless and for this simple app and it was fine. Also note “…system performance in this preview does not reflect system performance of the final release” [MSDN].

Also note that you don’t need the latest Windows 10 preview build to install the tools, the virtual machine I created was just running standard Windows 10 Pro, though as the following screenshot shows this seems to mean that there is no XAML visual preview in Visual Studio.

No XAML Preview without Windows 10 insider build


Overview of Steps

The following is an overview of the main steps required, once again you should consult MSDN for full details/steps required/warnings.

Step 1: Development Environment Setup

[MSDN]

You need:

  • Visual Studio 2015 Update 2 or newer (be sure to install the Universal Windows App Development Tools component)
  • Windows 10 SDK preview build 14295
  • Sign up for Windows Insider program
  • Create Windows Dev Center account
  • Network connection to your Xbox One

Step 2: Xbox One Setup

Detailed steps from MSDN.

Sign in to Xbox One.

Install Dev Mode Activation app from Xbox One store

Installing Dev Mode Activation app from Xbox One store

Once installed run the app:

Running Dev Mode Activation app

This can be a bit confusing as to what to do next, basically just leave it alone, at some point (perhaps hours) an “Update your Xbox” prompt will be displayed. Install the update and wait for it to complete and your Xbox restarted.

Open the Dev Mode Activation app again and following the instructions, to switch your console to into dev mode:

Switching Xbox One to developer mode

Tip: Make sure you’re connected to your wireless network before continuing…

Once restart is complete, open the Dev Home app:

Opening the Dev Home app

Take a note of the Xbox One’s IP address:

Xbox One IP Address

Step 3: Connection to Your Xbox One from Visual Studio

Create a new UWP project in Visual Studio.

Open the project properties and choose Remote Machine, enter the Xbox One’s IP address, and choose Universal (Unencrypted protocol).

Configuring Visual Studio to connect to Xbox One

Next run the app, and Visual Studio will ask you for a PIN, head back to the Xbox One dev app, and choose “Pair with Visual Studio”, you’ll be given a PIN that you can type into Visual Studio.

Pairing Visual Studio with Xbox One

Your app should now be installed and run on your Xbox One!

App XAML in Visual Studio

UWP app running on Xbox One

SHARE: