Reputation: 1512
I'm having some trouble with the output of a DateTime value. My computer's current culture is set to de-AT (Austria).
The following code
string s1 = DateTime.Now.ToString("d");
string s2 = string.Format("{0:d}", DateTime.Now);
results in s1 and s2 both having the correct value of "30.06.2009".
But when using the same format in XAML
<TextBlock Text="{Binding Source={x:Static sys:DateTime.Now}, StringFormat=d}"/>
the output is `"6/30/2009". It seems the XAML StringFormat ignores the current culture settings. This happens on both Vista and XP.
I don't want to specify a custom format, because the output should be formatted in the user's preferred culture setting.
Anybody with the same problem? Is this a bug in WPF?
Upvotes: 69
Views: 78787
Reputation: 7889
you could use an IValueConverter
(which takes in a culture parameter) and format the value as you wish, something I like is this nullable converter by Matt Hamilton
class NullableDateTimeConverter : ValidationRule, IValueConverter
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if (value == null || value.ToString().Trim().Length == 0) return null;
return new ValidationResult(
ConvertBack(value, typeof(DateTime?), null, cultureInfo) != DependencyProperty.UnsetValue,
"Please enter a valid date, or leave this value blank");
}
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return "";
DateTime? dt = value as DateTime?;
if (dt.HasValue)
{
return parameter == null ? dt.Value.ToString() : dt.Value.ToString(parameter.ToString());
}
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null || value.ToString().Trim().Length == 0) return null;
string s = value.ToString();
if (s.CompareTo("today") == 0) return DateTime.Today;
if (s.CompareTo("now") == 0) return DateTime.Now;
if (s.CompareTo("yesterday") == 0) return DateTime.Today.AddDays(-1);
if (s.CompareTo("tomorrow") == 0) return DateTime.Today.AddDays(1);
DateTime dt;
if (DateTime.TryParse(value.ToString(), out dt)) return dt;
return DependencyProperty.UnsetValue;
}
#endregion
}
heres the original
Upvotes: 1
Reputation: 2368
To apply the solution mentioned here do the following:
(1) Add a Startup event handler to the Application class in app.xaml:
<Application x:Class="MyApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
...
Startup="ApplicationStartup">
(2) Add the handler function:
private void ApplicationStartup(object sender, StartupEventArgs e)
{
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
}
WPF strings should then be formatted correctly according to culture.
Upvotes: 17
Reputation: 444
I Know that this is an aging question but this has always worked for me and sharing knowledge is a good thing. Since my apps always change language on the fly, the FrameworkElement.LanguageProperty.OverrideMetadata only works once and its no good for me, so behold:
this.Language = System.Windows.Markup.XmlLanguage.GetLanguage(ActiveLanguage.CultureInfo.IetfLanguageTag);
where (this) is the MainWindow, actually you have to do it in all rootelements (Windows). There you go simple enough.
Upvotes: 3
Reputation: 12846
If you want one particular language, you can set it on the top level element using xml:lang
.
For example:
<Window xml:lang="de-AT">
...
</Window>
Upvotes: 10
Reputation: 29594
Wrote about it some time ago on my blog:
This will tell you how to get WPF to use the right culture:
This will change the WPF culture on the fly when you modify the settings in the control panel:
Upvotes: 10