String formatting

Browse sample. Browse the sample

In a .NET Multi-platform App UI (.NET MAUI) app, it's sometimes convenient to use data bindings to display the string representation of an object or value. For example, you might want to use a Label to display the current value of a Slider. In this data binding, the Slider is the source, and the target is the Text property of the Label.

String formatting in code is typically accomplished with the static String.Format method. The formatting string includes formatting codes specific to various types of objects, and you can include other text along with the values being formatted. For more information, see Formatting Types in .NET for more information on string formatting.

String formatting can also be accomplished with data bindings by setting the StringFormat property of Binding (or the StringFormat property of the Binding markup extension) to a standard .NET formatting string with a placeholder:

<Slider x:Name="slider" />
<Label Text="{Binding Source={x:Reference slider},
                      Path=Value,
                      StringFormat='The slider value is {0:F2}'}" />

In XAML the formatting string is delimited by single-quote characters to help the XAML parser avoid treating the curly braces as another XAML markup extension. In this example, the formatting specification of F2 causes the value to be displayed with two decimal places.

Note

Using the StringFormat property only makes sense when the target property is of type string, and the binding mode is OneWay or TwoWay. For two-way bindings, the StringFormat is only applicable for values passing from the source to the target.

The following example demonstrates several uses of the StringFormat property:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:sys="clr-namespace:System;assembly=netstandard"
             x:Class="DataBindingDemos.StringFormattingPage"
             Title="String Formatting">

    <ContentPage.Resources>
        <Style TargetType="Label">
            <Setter Property="HorizontalTextAlignment" Value="Center" />
        </Style>
        <Style TargetType="BoxView">
            <Setter Property="Color" Value="Blue" />
            <Setter Property="HeightRequest" Value="2" />
            <Setter Property="Margin" Value="0, 5" />
        </Style>        
    </ContentPage.Resources>

    <StackLayout Margin="10">
        <Slider x:Name="slider" />
        <Label Text="{Binding Source={x:Reference slider},
                              Path=Value,
                              StringFormat='The slider value is {0:F2}'}" />
        <BoxView />
        <TimePicker x:Name="timePicker" />
        <Label Text="{Binding Source={x:Reference timePicker},
                              Path=Time,
                              StringFormat='The TimeSpan is {0:c}'}" />
        <BoxView />                              
        <Entry x:Name="entry" />
        <Label Text="{Binding Source={x:Reference entry},
                              Path=Text,
                              StringFormat='The Entry text is &quot;{0}&quot;'}" />
        <BoxView />
        <StackLayout BindingContext="{x:Static sys:DateTime.Now}">
            <Label Text="{Binding}" />
            <Label Text="{Binding Path=Ticks,
                                  StringFormat='{0:N0} ticks since 1/1/1'}" />
            <Label Text="{Binding StringFormat='The {{0:MMMM}} specifier produces {0:MMMM}'}" />
            <Label Text="{Binding StringFormat='The long date is {0:D}'}" />
        </StackLayout>
        <BoxView />        
        <StackLayout BindingContext="{x:Static sys:Math.PI}">
            <Label Text="{Binding}" />
            <Label Text="{Binding StringFormat='PI to 4 decimal points = {0:F4}'}" />
            <Label Text="{Binding StringFormat='PI in scientific notation = {0:E7}'}" />
        </StackLayout>
    </StackLayout>
</ContentPage>

In this example, the bindings on the Slider and TimePicker show the use of format specifications particular to double and TimeSpan data types. The StringFormat that displays the text from the Entry view demonstrates how to specify double quotation marks in the formatting string with the use of the &quot; HTML entity.

The next section in the XAML file is a StackLayout with a BindingContext set to an x:Static markup extension that references the static DateTime.Now property. The first binding has no properties:

<Label Text="{Binding}" />

This simply displays the DateTime value of the BindingContext with default formatting. The second binding displays the Ticks property of DateTime, while the other two bindings display the DateTime itself with specific formatting.

Note

If you need to display left or right curly braces in your formatting string, use a pair of them. For example, StringFormat='{{0:MMMM}}'.

The last section sets the BindingContext to the value of Math.PI and displays it with default formatting and two different types of numeric formatting:

String formatting.

ViewModels and string formatting

When you're using Label and StringFormat to display the value of a view that is also the target of a viewmodel, you can either define the binding from the view to the Label or from the viewmodel to the Label. In general, the second approach is best because it verifies that the bindings between the view and viewmodel are working.

This approach is shown in the following example:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataBindingDemos"
             x:Class="DataBindingDemos.BetterColorSelectorPage"
             Title="Better Color Selector">
    <ContentPage.BindingContext>
        <local:HslColorViewModel Color="Sienna" />
    </ContentPage.BindingContext>

    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Slider">
                <Setter Property="VerticalOptions" Value="Center" />
            </Style>

            <Style TargetType="Label">
                <Setter Property="HorizontalTextAlignment" Value="Center" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout Margin="20">
        <BoxView Color="{Binding Color}"
                 HeightRequest="100"
                 WidthRequest="100"
                 HorizontalOptions="Center" />
        <StackLayout Margin="10, 0">
            <Label Text="{Binding Name}" />
            <Slider Value="{Binding Hue}" />
            <Label Text="{Binding Hue, StringFormat='Hue = {0:F2}'}" />
            <Slider Value="{Binding Saturation}" />
            <Label Text="{Binding Saturation, StringFormat='Saturation = {0:F2}'}" />
            <Slider Value="{Binding Luminosity}" />
            <Label Text="{Binding Luminosity, StringFormat='Luminosity = {0:F2}'}" />
        </StackLayout>
    </StackLayout>
</ContentPage>    

In this example, there are three pairs of Slider and Label elements that are bound to the same source property in the HslColorViewModel object. Each Label that accompanies a Slider has a StringFormat property to display each Slider value:

Better color selector.