Reputation:
In WPF 3.5SP1 i use the last feature StringFormat in DataBindings:
<TextBlock Text="{Binding Path=Model.SelectedNoteBook.OriginalDate, StringFormat='f'}"
FontSize="20" TextTrimming="CharacterEllipsis" />
The problem I face is that the date is always formatted in English...although my system is in French ? How can i force the date to follow system date?
Upvotes: 125
Views: 54177
Reputation: 538
If you are working on code rather than XAML, you can set the ConverterCulture as follows:
binding.ConverterCulture = System.Globalization.CultureInfo.CurrentCulture;
Kudos to @KZeise for pointing out the subtle difference between using the default culture definition and using the user's customized culture definition.
Upvotes: 0
Reputation: 123
As already stated, XAML defaults to the invariant culture (en-US), and you can use
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(
XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
to set the culture to the default culture for the language of the current culture. But the comment is wrong; this does not use the current culture, as you will not see any customizations the user might have made, it will always be the default for the language.
To actually use the current culture with customizations, you will need to set the ConverterCulture
together with the StringFormat
, as in
Text="{Binding Day, StringFormat='d', ConverterCulture={x:Static gl:CultureInfo.CurrentCulture}}"
with the gl
defined as a global namespace in your root element
xmlns:gl="clr-namespace:System.Globalization;assembly=mscorlib"
Upvotes: 12
Reputation: 2761
The full code to switch the localization also in elements like <Run />
is this:
Private Shared Sub SetXamlBindingLanguage()
'' For correct regional settings in WPF (e.g. system decimal / dot or comma)
Dim lang = System.Windows.Markup.XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)
FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(TextElement), New FrameworkPropertyMetadata(lang))
FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(DefinitionBase), New FrameworkPropertyMetadata(lang))
FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(FixedDocument), New FrameworkPropertyMetadata(lang))
FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(FixedDocumentSequence), New FrameworkPropertyMetadata(lang))
FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(FlowDocument), New FrameworkPropertyMetadata(lang))
FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(TableColumn), New FrameworkPropertyMetadata(lang))
FrameworkElement.LanguageProperty.OverrideMetadata(GetType(FrameworkElement), New FrameworkPropertyMetadata(lang))
End Sub
Upvotes: 7
Reputation: 1
If you want to change culture info at runtime, you could use a behavior (see below)
public class CultureBehavior<TControl> : Behavior<TControl>
where TControl : FrameworkElement
{
private readonly IEventAggregator _eventAggregator;
private readonly Action<CultureInfo> _handler;
public CultureBehavior()
{
_handler = (ci) => this.AssociatedObject.Language = XmlLanguage.GetLanguage(ci.IetfLanguageTag);
_eventAggregator = IoC.Container.Resolve<IEventAggregator>();
}
protected override void OnAttached()
{
base.OnAttached();
_eventAggregator
.GetEvent<LanguageChangedEvent>()
.Subscribe(_handler);
_handler.Invoke(CultureInfo.CurrentCulture);
}
protected override void OnDetaching()
{
_eventAggregator
.GetEvent<LanguageChangedEvent>()
.Unsubscribe(_handler);
base.OnDetaching();
}
}
Upvotes: 0
Reputation: 4716
// Ensure the current culture passed into bindings is the OS culture.
// By default, WPF uses en-US as the culture, regardless of the system settings.
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(
XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
From Creating an Internationalized Wizard in WPF
Upvotes: 232
Reputation: 391
I just wanted to add that loraderon's answer works great in most cases. When I put the following line of code in my App.xaml.cs, the dates in my TextBlocks are formatted in the correct culture.
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(System.Windows.Markup.XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
I say 'most cases'.For example, this will work out of the box:
<TextBlock Text="{Binding Path=Date, StringFormat={}{0:d MMMM yyyy}}" />
--> "16 mei 2013" (this is in Dutch)
...but when using Run's in a TextBlock, the DateTime is formatted in the default culture.
<TextBlock>
<Run Text="Datum: " />
<Run Text="{Binding Path=Date, StringFormat={}{0:d MMMM yyyy}, Mode=OneWay}" />
</TextBlock>
--> "Datum: 16 may 2013" (this is in English, notice the
name of the month "may" vs. "mei")
For this to work, I needed Gusdor's answer, namely adding ConverterCulture={x:Static gl:CultureInfo.CurrentCulture} to the Binding.
<TextBlock>
<Run Text="Datum: " />
<Run Text="{Binding Path=Date, StringFormat={}{0:d MMMM yyyy}, ConverterCulture={x:Static gl:CultureInfo.CurrentCulture}, Mode=OneWay}" />
</TextBlock>
--> "Datum: 16 mei 2013" (=Dutch)
I hope this additional answer will be of use to someone.
Upvotes: 15
Reputation: 561
Just insert the culture shortcut to the top-level tag:
xml:lang="de-DE"
e.g.:
<Window x:Class="MyApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xml:lang="de-DE"
Title="MyApp" Height="309" Width="497" Loaded="Window_Loaded">....</Window>
Upvotes: 12
Reputation: 14334
Define the following xml namespace:
xmlns:gl="clr-namespace:System.Globalization;assembly=mscorlib"
Now behold this fantastic fix:
<TextBlock Text="{Binding Path=Model.SelectedNoteBook.OriginalDate, StringFormat='f', ConverterCulture={x:Static gl:CultureInfo.CurrentCulture}" FontSize="20"TextTrimming="CharacterEllipsis" />
I'm well aware this isn't a global fix and you will require it on each of your Bindings but surely that is just good XAML? As far as I'm aware, the next time the binding updates it will use the correct CultureInfo.CurrentCulture
or whatever you have supplied.
This solution will immediately update your Bindings with the correct values but it seems like a lot of code for something so rare and innocuous.
Upvotes: 100
Reputation: 38465
If you need to change the language while the program is running you can just change the Language property on your root element (im unsure if this has an instant effect or if the sub element have to be recreated, in my case this works at least)
element.Language = System.Windows.Markup.XmlLanguage.GetLanguage(culture.IetfLanguageTag);
Upvotes: 8