Paul Martinez
Paul Martinez

Reputation: 562

WPF Culture issue

I would like to display in the main page of my app the date in the french format: (dd/MM/yyyy) I work with Entity Framework objects and dates are properties of an entity list which is binded to a combobox in the xaml file.

I manage to get through this by adding this code when my app starts:

FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));

BUT I get a new problem with this add : All my decimal numbers use comma instead of using dot in the other pages of my app...ma app doesn't work anymore with this change...

So could you give me a solution which solve the problem in a global way... To summarize I need French Date format and decimal with dot. I would prefer to not have to change the culture for each line of my code.

I already tried to add this line in the concerned page but It didn't work.

 Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;

Thanks

Upvotes: 0

Views: 652

Answers (2)

Mike Strobel
Mike Strobel

Reputation: 25623

If all you want to do is change the formatting of dates in a single control, then changing the application-wide locale is not the way to do that. Set a custom ItemTemplate on your ComboBox, and set the StringFormat on your Binding to 'dd/MM/yyyy'.

If you really need to change the date format across your entire application, but you want to leave the other formats untouched, you can apply a custom locale at startup based on the current one, but getting it to work properly in WPF requires some nasty reflection.

var currentCulture = CultureInfo.CurrentCulture;
if (currentCulture.IsReadOnly)
    currentCulture = new CultureInfo(currentCulture.IetfLanguageTag, true);

currentCulture.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";

// ...adjust other patterns accordingly...

// WARNING: Ugly reflection hacking ahead...

var defaultValueField = typeof(PropertyMetadata).GetField(
    "_defaultValue",
    BindingFlags.NonPublic | BindingFlags.Instance);

var equivalentCultureField = typeof(XmlLanguage).GetField(
    "_equivalentCulture",
    BindingFlags.NonPublic | BindingFlags.Instance);

if (defaultValueField != null &&
    equivalentCultureField != null)
{
    var xmlLanguage = XmlLanguage.GetLanguage(currentCulture.IetfLanguageTag);

    equivalentCultureField.SetValue(
        xmlLanguage,
        currentCulture);

    defaultValueField.SetValue(
        FrameworkElement.LanguageProperty.DefaultMetadata,
        xmlLanguage);
}

Thread.CurrentThread.CurrentCulture = currentCulture;
Thread.CurrentThread.CurrentUICulture = currentCulture;

Be sure to do that from your main thread, as early in the startup process as possible. Be aware, however, that this will affect the entire program and not just the WPF visual bits. For example, it may impact the timestamp format in your logs, among other things.

On a personal note, as someone who works in a company with multiple locales, I find it much less confusing to simply use the ISO standard yyyy-MM-dd format for all dates. The d/MM/yyyy and MM/d/yyyy formats need to go away.

Upvotes: 4

Jack
Jack

Reputation: 13

One solution is to have different resource files with same keys and values based on region and use culture to load respective region value

Upvotes: 0

Related Questions