Link Search Menu Expand Document


Data Binding

  1. Data Binding
    1. Introduction
    2. Declaring a Binding
    3. Binding Paths
    4. Model Binding
    5. Multi Binding / Transform Binding
    6. Format String Binding
    7. Binding to Collections
    8. Negated Binding
    9. Localization Binding
    10. Binding Cheat Sheet

Introduction

Data binding is a way to connect data to your views and to keep data synchronized.

Declaring a Binding

Bindings are declared using {} syntax:

<NewView MyBoolValue="t:bool = True">
     
  <CheckBox IsChecked="{MyBoolValue}" />
   
</NewView>

If the checkbox is toggled IsChecked will get a new value that will propagate to MyBoolValue. And if you change MyBoolValue in code the checkbox will be updated.

Binding Paths

You can bind to nested properties:

<MyView>
     
  <Group>
    <InputField Id="Input" />
    <Label Text="{Input.Text}" />   
  </Group>
   
</MyView>

Here we bind the nested Input.Text property to the label text.

Model Binding

Binding directly to your model by using the @ symbol:

MyView.xml

<MyView>
     
  <Label Text="{@MyModelValue}" />
   
</MyView>

This assumes there is a property called MyModelValue in the Models static class. You can declare it like this:

MyModel.cs

namespace Delight
{
    public partial class Models
    {
        public static string MyModelValue = "Hello";
    }
}

Multi Binding / Transform Binding

You can bind one or more values to a single target property and transform the values using embedded code expressions. You create an embedded expression using the $ prefix:

MyView.xml

<MyView>
  
  <Group>
    <InputField Id="Input1" />
    <InputField Id="Input2" />
    <Label Text="$ Sum({Input1.Text}, {Input2.Text})" />   
  </Group>
   
</MyView>

MyView.cs

namespace Delight
{
    public partial class MyView
    {
        public string Sum(string input1, string input2)
        {
            if (int.TryParse(input1, out var number1) && 
                int.TryParse(input2, out var number2))
            {
                return (number1 + number2).ToString();
            }

            return "specify two numbers";
        }
    }
}

If either Input1.Text or Input2.Text changes value the values are transformed and propagated to the label text using the Sum() method. See the guide on embedding C# code into your view XML for more information.

Format String Binding

To transform multiple values into a formatted string using the following syntax:

<MyView>
  
  <Group>
    <InputField Id="Firstname" />
    <InputField Id="Lastname" />
    <Label Text="Hello {Firstname.Text} {Lastname.Text}!" />
  </Group>
   
</MyView>

You can also add format modifiers to control things like number of decimals printed:

<MyView>
  
  <Group Orientation="Vertical">
    <Slider Id="Slider1" Orientation="Vertical" 
            Min="20" Max="180" Value="50" />
    <Label Text="{Slider1.Value:0.0}" />
  </Group> 
   
</MyView>

It translates to the following C# operation:

Label.Text = String.Format("{0:0.0}", Slider1.Value);

It prints the slider value with one decimal. For a comprehensive list of string formatting options check out the String.Format Method documentation.

Binding to Collections

You can bind to collections using the {item in MyCollection} syntax:

<HighscoreTest>
  
    <List Id="HighscoreList" Items="{highscore in @Highscores}" 
          Width="300">
      <ListItem Width="100%">
        <Label Text="{highscore.Name}: {highscore.ScoreText}"/>
      </ListItem> 
    </List>
   
</HighscoreTest>

Here we bind the collection Highscores that resides in our model to the list view. The list view dynamically generates a ListItem view for each item in the collection. To bind to item properties we use the name highscore we’ve given each item (we can name it whatever we want) to access the properties. It works similar to the foreach statement in C#.

Negated Binding

When binding to a boolean we have the option to negate the value using the ! symbol:

<NewView MyBoolValue="t:bool = True">
   
  <Group>   
    <CheckBox IsChecked="{MyBoolValue}" />
    <CheckBox IsChecked="{!MyBoolValue}" />
  </Group>
   
</NewView>

The second checkbox will always have the negated value.

Localization Binding

To bind to localized labels we can use the @Loc syntax:

<NewView>

  <Label Text="{@Loc.Greeting1}" /> 
   
</NewView>

This binds to the Greeting1 label in the localization dictionary.

Binding Cheat Sheet

Binding Example Syntax
Simple Binding <CheckBox IsChecked="{MyBoolValue}" />
Binding Path <Label Text="{Player.Name}" />
Model Binding <Label Text="{@MyModelValue}" />
Multi Binding /
Transform Binding
<Label Text="$ Sum({Number1}, {Number2})" />
<Label Text="$ Math.Pow({Num1}, {Num2}).ToString()" />
Format String <Label Text="Hello {Firstname} {Lastname}!" />
<Label Text="{Progress:0.0} %" />
Collection Binding <List Items="{highscore in @Highscores}">
Item Index <Label Text="{highscore.Index}" />
<Label Text="{highscore.ZeroIndex}" />
Negated Binding <CheckBox IsChecked="{!MyBoolValue}" />
Localization Binding <Label Text="{@Loc.Greeting1}" />