DEV Community

Saulo Dias
Saulo Dias

Posted on

How to Bind to a DataTemplate in UWP

First and foremost, you can't bind to the outside context of a DataTemplate when using x:Bind, even so it is highly recommended to use x:Bind for everything. You might argue that Binding will work for some cases, and that is true. However, if you are using MVVM, you don't want to use Binding, specially when working with Layouts in an ItemsRepeater, as it will not work in a predictable way.

Now that we are on the same page, let's agree on two rules:

  1. Every model (the type or class of the object) must have all of the data and behavior properties that the data templates will use. That is also valid and specially important for things like visibility properties and other properties which will define how the component renders visually.

    NOTE: If you do not like this approach, you can always create a base class without any behavior property (e.g.: Item), and have a new class inherit from it where the rendering and behavior properties are then implemented (e.g.: ItemViewModel).

  2. Every data template must have a type associated to it. This not only will save you some time with suggestions when you are writing your x:Binds, but without it you will most likely get typing errors related to the DataTemplate.

Rendering a list of users

In this example we have a User model with some basic properties:

using System;

namespace MySolution.Domain.Models
{
    public class User
    {
        public Guid Id { get; set; }
        public string GivenName { get; set; }
        public string Surname { get; set; }
        public string DisplayName { get; set; }
        public string Mail { get; set; }
    }
}
Enter fullscreen mode Exit fullscreen mode

The example below has an ItemsRepeater to render a list of users. Notice how the DataTemplate is configured outside of the ItemsRepeater and how we reference it as static resource. At first this might not look like a big deal, but besides better organizing the code, this will make a big difference when working with dynamic templates.

<UserControl
    x:Class="MySolution.Controls.UsersList"
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"
    xmlns:models="using:MySolution.Domain.Models"
    xmlns:xamlc="using:Microsoft.UI.Xaml.Controls"
    mc:Ignorable="d">
    <UserControl.Resources>
        <DataTemplate x:Key="UserItemTemplate" x:DataType="models:User">
            <StackPanel>
                <TextBlock
                    MaxWidth="180"
                    FontWeight="SemiBold"
                    Foreground="{x:Bind Foreground}"
                    Text="{x:Bind User.DisplayName, Mode=OneWay}"
                    TextTrimming="CharacterEllipsis" />
                <TextBlock
                    MaxWidth="180"
                    FontWeight="SemiLight"
                    Foreground="{x:Bind Foreground}"
                    Text="{x:Bind User.Mail, Mode=OneWay}"
                    TextTrimming="CharacterEllipsis" />
            </StackPanel>
        </DataTemplate>
    </UserControl.Resources>

    <xamlc:ItemsRepeater
        ItemTemplate="{StaticResource UserItemTemplate}"
        ItemsSource="{x:Bind ItemsSource, Mode=OneWay}">
        <xamlc:ItemsRepeater.Layout>
            <xamlc:StackLayout x:Name="layout" Orientation="Vertical" />
        </xamlc:ItemsRepeater.Layout>
    </xamlc:ItemsRepeater>

</UserControl>
Enter fullscreen mode Exit fullscreen mode

It is also important to highlight that we must explicitly declare the data type (x:DataType="models:User"), following the second rule mentioned before.

Let me know if you have any questions or suggestions in the comments below.

Top comments (1)

Collapse
 
stormytalent profile image
StormyTalent

Really interesting.
Thanks for sharing!