greenshade greenshade - 3 months ago 25
C# Question

Culture difference between Label and TextBlock

I have been playing with

WPF
for a while and I came across an interesting thing. When I bind
DateTime
object to the
Label
's content then I see locally formatted representation of the date. However, when I bind to the
TextBlock
's Text property then I actually see English (Invariant?) one.

It seems that
TextBlock
is using some sort of converter whereas
Label
is just calling
ToString
method but I am not sure about it.

If so, why doesn't the
Label
use the converter too?

Could somebody explain to me why is it working the way it is? I provide a short sample to let you guys inspect what's going on:

// MainWindow.xaml
<Window x:Class="BindConversion.MainWindow"
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"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel HorizontalAlignment="Center" Margin="3">
<StackPanel>
<Label Content="{Binding Dt}"/>
<TextBlock Text="{Binding Dt}"/>
</StackPanel>
</StackPanel>
</Window>

// MainWindow.xaml.cs
using System;
using System.Windows;

namespace BindConversion
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public DateTime Dt { get; set; }
public MainWindow()
{
InitializeComponent();

DataContext = this;
Dt = DateTime.Now;
}
}
}

Answer

If you take a closer look to Label you will see that it derives from ContentControl.

Content property is displayed by a ContentPresenter where in the docs it is said the following:

If there is a TypeConverter that converts the type of Content to a UIElement, the ContentPresenter uses that TypeConverter and the resulting UIElement is displayed.

Now there is a DateTimeConverter inheriting from TypeConverter, the following snippet produces exactly the same string than a Label does:

var dateTimeConverter = new DateTimeConverter();
var convertToString = dateTimeConverter.ConvertToString(DateTime.Now);

References:

https://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/system.componentmodel.datetimeconverter(v=vs.110).aspx

Comments