24

View:

<TextBlock Text="{Binding Date}"/>

I want to format the Date to "dd/MM/yyyy", in other words, without the time.

I tried it: <TextBlock Text="{Binding Date, StringFormat={}{0:dd/MM/yyyy}}"/>, but it doesn't work.

Gives me an error: The property 'StringFormat' was not found in type 'Binding'.

Blacktempel
  • 3,935
  • 3
  • 29
  • 53
developer033
  • 24,267
  • 8
  • 82
  • 108

9 Answers9

25

The best and the easiest way would be to use a converter to which you pass the Date and get the formatted string back. In e.g. MyNamespace.Converters namespace:

public class DateFormatConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value == null)
            return null;

        DateTime dt = DateTime.Parse(value.ToString());
        return dt.ToString("dd/MM/yyyy");
    }

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

And in your xaml just reference the converter and add the following converter:

xmlns:conv="using:MyNamespace.Converters" 

in your xaml page and in page.resources add this

<conv:DateFormatConverter x:Name="DateToStringFormatConverter"/>

<TextBlock Text="{Binding Date, Converter={StaticResource DateToStringFormatConverter}"/>
Mormegil
  • 7,955
  • 4
  • 42
  • 77
CodeNoob
  • 757
  • 5
  • 15
7

There is no property named StringFormat in Binding class. You can use Converter and ConverterParameter to do this. You can refer to Formatting or converting data values for display.

For example here, I bind the date of a DatePicker to the text of a TextBlock.

XAML:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.Resources>
        <local:DateFormatter x:Key="DateConverter"/>
    </Grid.Resources>
    <DatePicker Name="ConverterParmeterCalendarViewDayItem"></DatePicker>
    <TextBlock Height="100" VerticalAlignment="Top" Text="{Binding ElementName=ConverterParmeterCalendarViewDayItem, Path=Date, Converter={StaticResource DateConverter},ConverterParameter=\{0:dd/MM/yyyy\}}" />
</Grid>

code behind, the DateFormatter class:

public class DateFormatter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var a = language;
        // Retrieve the format string and use it to format the value.
        string formatString = parameter as string;
        if (!string.IsNullOrEmpty(formatString))
        {
            return string.Format(formatString, value);
        }

        return value.ToString();
    }

    // No need to implement converting back on a one-way binding
    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return DependencyProperty.UnsetValue;
    }
}
Treycos
  • 7,373
  • 3
  • 24
  • 47
Grace Feng
  • 16,564
  • 2
  • 22
  • 45
  • Came to give exactly the same answer. The best way it can be done is with a converter, as shown above, unless you change the Date to a string in code-behind and format it there instead. [Info on DateTime formats](https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx) – James Croft Jan 11 '16 at 09:09
  • Unfortunately, it isn't working here..The type 'local:DateFormatter' was not found. What am I missing? – developer033 Jan 11 '16 at 12:22
  • You need to create a class named DateFormatter, please see my `DateFormatter` class. – Grace Feng Jan 11 '16 at 12:56
  • @developer033 Ok, please see my shared sample [StringFormatInBinding](http://1drv.ms/1P57M1N). – Grace Feng Jan 12 '16 at 01:17
  • @GraceFeng-MSFT I downloaded your project and put everything equal to its... Same error: "The type 'local:DateFormatter' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.". – developer033 Jan 12 '16 at 02:44
  • ....Did you delete this `xmlns:local="using:'your project'"`? If not, there is some problem with the xaml designer, it may be tagged as a error, but you can still run this project and it should work fine. – Grace Feng Jan 12 '16 at 04:12
  • @GraceFeng-MSFT - Your OneDrive link doesn't work any more. Could you update it? – dex3703 Dec 13 '16 at 22:06
  • If XAML complains about not finding reference to your DateFormatter, make sure the xmls:local variable points to the right namespace. You can always make a new xmls reference called whatever you like to point to a specific file. – stevokk Aug 14 '17 at 23:50
  • This is for the `Windows.UI.Xaml.Data` namespace. For the `IValueConverter` in `System.Windows.Data` the method signature on Convert and ConvertBack changes the `string language` parameter to `CultureInfo culture`. – BurnsBA May 18 '21 at 01:39
7

I know this is late but I had the same question and came up with this solution. Maybe not the shortest but pure XAML.

    <TextBlock>
        <Run Text="{x:Bind Foo.StartDate.Day}"/>.<Run Text="{x:Bind Foo.StartDate.Month}"/>.<Run Text="{x:Bind Foo.StartDate.Year}"/>
    </TextBlock>
Max
  • 71
  • 1
  • 3
6

Since 14393, you can use functions in x:Bind.

This means you can format your date like:

Text="{x:Bind sys:String.Format('{0:dd/MM/yyyy}', ViewModel.Date)}"

Just ensure you have included a reference to the System namespace:

<Page 
     xmlns:sys="using:System"
     ...
mcalex
  • 6,628
  • 5
  • 50
  • 80
4

why to complicate? You can use compiled data binding

{x:Bind ViewModel.PropertyWithDateTime.ToString("....")}
Ivan
  • 1,254
  • 12
  • 25
1

There is an excellent example here:

Example from MSDN

if your converter class is in a different namespace (as suggested to be in a separate folder) you can add

xmlns:conv="using:MyNamespace.Converters"

and use it like this:

<UserControl.Resources>
  <conv:DateToStringConverter x:Key="Converter1"/>
</UserControl.Resources>

the rest should stay the same as in the example from the link.

Christoph
  • 323
  • 4
  • 16
0

The nice thing about StringFormat is that it allows you to specify the format of the output. Here is a converter I use that allows you to specify the format.

public sealed class DateTimeToStringConverter : IValueConverter
{
    public static readonly DependencyProperty FormatProperty =
        DependencyProperty.Register(nameof(Format), typeof(bool), typeof(DateTimeToStringConverter), new PropertyMetadata("G"));

    public string Format { get; set; }

    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value is DateTime dateTime && value != null)
        {
            return dateTime.ToString(Format);
        }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return DateTime.ParseExact(value.ToString(), Format, CultureInfo.CurrentCulture);
    }
}

How to use (example with multiple formats):

<Page.Resources>
    <ResourceDictionary>
        <converters:DateTimeToStringConverter 
            x:Name="dateStringConverter" 
            Format="dd-MM-yyyy" />
        <converters:DateTimeToStringConverter
            x:Name="timeStringConverter"
            Format="HH:mm" />
    </ResourceDictionary>
</Page.Resources>

<!-- Display the date -->
<TextBlock Text="{Binding Path=Date, Converter={StaticResource dateStringConverter}}" />    

<!-- Display the time -->
<TextBlock Text="{Binding Path=Date, Converter={StaticResource timeStringConverter}}" />
Knelis
  • 6,782
  • 2
  • 34
  • 54
-1

Try this,

<Label x:Name="LblEstEndTime" Text="{Binding EndTime, StringFormat='Est. End Time: {0:MM/dd/yy h:mm tt}'}" Style="{StaticResource ListCellSubTitleStyle}" VerticalOptions="EndAndExpand" />

-1

You can do this in xml itself. Here...

<DatePicker 
SelectedDate="{Binding Date, Mode=TwoWay}" 
Text="{Binding ., StringFormat='dd/MM/yyyy'}"/>
Shaamil Ahmed
  • 378
  • 2
  • 7
  • 4
    `StringFormat` does not exist in UWP's `Binding` class. Furthermore, XML is not the same as XAML. XAML is an XML-based technology, but XAML and XML are not interchangeable terms. – The Pademelon May 03 '19 at 08:35