Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

Debugging WinRT/XAML bindings

Visual Studio 2012 may not (yet?) support debugging of XAML bindings debugging in WinRT/Metro-style applications in a way we’re used to from programming WPF and Silverlight (a.k.a. XAML breakpoints), but basic notifications of failed bindings in the output window seems to be present and working.

Let’s look at the basic set up (new blank application).

MainPage.xaml – DataContext is set to the same page class to keep it simple;  TextBlock’s text is bound to a MyBinding property.

<Page
    x:Class="App1.MainPage"
    IsTabStop="false"
    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"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    mc:Ignorable="d">
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="{Binding BindingText}" VerticalAlignment="Center" HorizontalAlignment="Center" />
    </Grid>
</Page>

MainPage.xaml.cs

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    public string BindingText { get { return "OK"; } }
}

BindingText property in the code-behind class that TextBlock is bound to, exposes a fixed string.

Running this project should greet you with the “OK” string  centered on the screen, meaning the binding worked as expected.

Changing the name of the binding property should break the binding.

public string BindText { get { return "OK"; } }

After starting now broken app, we’re greeted with an empty screen and no exceptions thrown. We can, however, observe a subtle notification about thee binding failure in the Output window:

Error: BindingExpression path error: 'BindingText' property not found on 'App1.MainPage'. BindingExpression: Path='BindingText' DataItem='App1.MainPage'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')

Because such notifications are really easy to miss, there’s now a way to subscribe to binding errors notifications right from your WinRT code – Application’s DebugSettings property exposes a BindingFailed event you can subscribe to. This event will be called whenever binding fails (well, not exactly always , but whenever the binding failure message gets written to the Output window, you can be sure it will get called.

You can use this event to make sure that caught binding errors will surely get your attention, by i.e. displaying the exception message all over the place:

sealed partial class App : Application
{
    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
        DebugSettings.BindingFailed += OnDebugSettingsOnBindingFailed;
    }

    private void OnDebugSettingsOnBindingFailed(object sender, BindingFailedEventArgs args)
    {
        new MessageDialog(args.Message).ShowAsync();
    }
    ...
}

image

Unfortunately, the binding failure message text is currently just the only thing you’re provided with in the event handler, but you can still parse it manually and decide whether you want it displayed or not.

Other BindingSettings options enable you to override the above-described behavior – setting IsBindingTrackingEnabled to false (it’s true by default) will disable failed binding notifications: the event will not get called and there will be no trace in the Output window.
Additionally, both kind of notifications only work when the debugger is attached. That means that running the application with Ctrl+F5 (Start Without Debugging) won’t display any notification either.

There is, however, one tiny difference between when notifications are presented – Output window will never write the exception message when running in the Release configuration, while the event will still get called.

To summarize: while we wait for a proper XAML debugging in WinRT, tracking the output window is the default option to catch binding failures. Subscribing to BindingSettingsBindingFailed event will give you some more flexibility and display visibility, and it also works when running in the Release configuration.