In an usual application sometimes you need to “adapt” the values from the view model. This is normally done using StringFormat, but we’ll see some other options as well.

Simple StringFormat with binding escape

Let’s say that you need to display a temperature in degrees. In the view model you have just the numerical value and in the interface you want to append the °C string to make it clear what type of degrees are displayed. Here’s how that’s done:

<TextBlock Text="{Binding CelsiusTemp, StringFormat={}{0}°C}" />

MultiBinding

The zero from XAML binding is actually the first binding. In the next example Name is the {0} part and ID is the {1} part:

<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="{}{0} + {1}">
            <Binding Path="Name" />
            <Binding Path="ID" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

There are however some other ways you can concatenate string values in XAML. Let’s review them quickly:

  • TextBlock with Run text
  • Using StackPanel to group
  • Using Converters

TextBlock with Run text

TextBlock supports an inner element called Run which can be helpful when you want to concatenate more things.

<TextBlock>
  <Run Text="Temperature is " />
  <Run Text="{Binding CelsiusTemp}" />
  <Run Text="°C" />
</TextBlock>

Using StackPanel to group

In this case you can just dump everything in a StackPanel having the Orientation set to Horizontal.

<StackPanel Orientation="Horizontal">
    <TextBlock Text="Temperature is "/>
    <TextBlock Text="{Binding CelsiusTemp}"/>
    <TextBlock Text="°C"/>
</StackPanel>

Using Converter

And the last example, although I wouldn’t really use it in this case (but shown nonetheless just for completeness sake):

public class TemperatureConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        return $"Temperature is {value} °C";
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        throw new NotImplementedException();
    }
}

And here’s how to use it in XAML:

<Grid>
    <Grid.Resources>
        <local:TemperatureConverter x:Key="temperatureConverter"/>
    </Grid.Resources>
    <TextBlock Text="{Binding CelsiusTemp, Converter={StaticResource temperatureConverter}}"/>
</Grid>

Most common formatting specifiers

Formatting numbers using 2 decimal points is done using F2 - F means floating point and the following digit is the number of decimal digits. In this case I used 2, but it can be any value. If you want to show only the integral part then use F0.

If you also want to display the thousands separator you can use N2.

<!-- Consider CelsiusTemp = 1234.5678 -->
<!-- Also take note that the values will be rounded! -->

<!-- This will be: 1234.57 -->
<TextBlock Text="{Binding CelsiusTemp, StringFormat={}{0:F2}}"/>

<!-- This will be: 1235 -->
<TextBlock Text="{Binding CelsiusTemp, StringFormat={}{0:F0}}"/>

<!-- This will be: 1,234.57 -->
<TextBlock Text="{Binding CelsiusTemp, StringFormat={}{0:N2}}"/>

<!-- This will be: 1,235 -->
<TextBlock Text="{Binding CelsiusTemp, StringFormat={}{0:N0}}"/>

Here are some more examples showing how to display currency and dates:

<Window x:Class="PlayingWithXAML.MainWindow"
        x:Name="wnd"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Width="300"
        Height="200">
    <StackPanel Margin="10">
        <TextBlock Text="{Binding ElementName=wnd, Path=ActualWidth, StringFormat=Window width: {0:#,#.0}}" />
        <TextBlock Text="{Binding ElementName=wnd, Path=ActualHeight, StringFormat=Window height: {0:C}}" />
        <TextBlock Text="{Binding Source={x:Static system:DateTime.Now}, StringFormat=Date: {0:dddd, MMMM dd}}" />
        <TextBlock Text="{Binding Source={x:Static system:DateTime.Now}, StringFormat=Time: {0:HH:mm}}" />
    </StackPanel>
</Window>

Resources