Tuesday, June 14, 2016

UWP Design Preview with x:Bind

When I work with XAML, I really enjoy using the full toolset. Blend offers a great complimentary toolset to Visual Studio 2015 and the Design tab lets me preview the content as I build it. As I understand it, the Design tab in VS 2015 runs the same version of the preview as Blend.

The new x:Bind syntax in XAML for Windows 10 UWP provides a compile type check; improving my confidence that I'm headed down the right path as I build the view. I was surprised to learn that x:Bind constrains the output of the sample data in the Design tab of Blend or Visual Studio 2015.

By default, the Design tab will simply show the property name of an x:Bind statement. That's better than nothing, but still a large constraint. I'd like to see my specific sample data.

I couldn't solve this problem with timer (a long running joke at my shop), but I did figure out a way. The following example shows how to display your custom sample data in the Design tab when data binding with the new x:Bind syntax.

View Model

Pretty simple, nothing fancy. The run-time data is not implemented, this is just about the design time experience:

using Windows.ApplicationModel;

namespace MyApp
{
    public class MainPageViewModel
    {
        public MainPageViewModel()
        {
            if (DesignMode.DesignModeEnabled)
            {
                Name = "Alice";
            }
        }

        public string Name { get; set; }
    }
}

View Code-Behind

One of the common tricks in using x:Bind is to include a "ViewModel" property in order to get benefits of the MVVM separation. x:Bind uses the code-behind file instead of a DataContext property to fulfill databinding requests. In addition to compile-time checking; the app avoids run-time reflection, which boosts performance over the standard Binding syntax.

using Windows.UI.Xaml.Controls;

namespace MyApp
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            ViewModel = new MainPageViewModel();
        }

        public MainPageViewModel ViewModel { get; set; }
    }
}

Standard View: XAML 

This view is uses the x:Bind syntax to display the property "Name" hanging off the ViewModel object. If I make a mistake in the x:Bind statement, the compiler will yell at me.

<Page x:Class="MyApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:MyApp"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">

    <Grid>
        <TextBlock Text="{x:Bind ViewModel.Name}" /> 
    </Grid>
    
</Page>

Standard View: Design

Some say "standard", I say "broken". This design view doesn't show my sample data, but shows the property name instead.


Sample Data View: XAML 

It turns out that by specifying the design-time data context (which is ignored at run-time), the Design tab can regain access to the sample data.


<Page x:Class="MyApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:MyApp"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d"
      d:DataContext="{d:DesignInstance Type=local:MainPage,IsDesignTimeCreatable=True}">

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


</Page>

Sample Data View: Design



Summary

By adding the d:DataContext attribute to your XAML view, you can instruct the design time to create another instance of your code-behind file, which happens to have a ViewModel property with your expected sample data. It's a little weird, albeit hacky, to mix the DataContext and code-behind instances like this but it makes the sample data available.

Note, this example says nothing about the View Model is applied at run-time, INotifyPropertyChanged, and other ceremonial aspects of XAML and MVVM, I'm just demonstrating the sample data in the Design tab with x:Bind in this post.


No comments:

Post a Comment