3

Is there any way to set the StringFormat for all DateTime objects globally independently of the CultureInfo in my WPF Application?

I use bindings to this kind of objects from the whole application, like this:

<DataGridTextColumn Header="Date" Binding="{Binding Date}"/>    

and I want to avoid having to add the StringFormat parameter to every binding. I have tried to override the current culture DateTimeFormat parameters like this:

public void SetDateTimeFormat()
{
    culture = Thread.CurrentThread.CurrentUICulture;
    var newCulture = new CultureInfo(culture.Name);

    // Set desired date format here
    newCulture.DateTimeFormat.ShortDatePattern = "dd/MMM/YYYY";
    newCulture.DateTimeFormat.LongDatePattern = "dd/MMM/YYYY";
    newCulture.DateTimeFormat.ShortTimePattern = "dd/MMM/YYYY";
    newCulture.DateTimeFormat.LongTimePattern = "dd/MMM/YYYY";
    newCulture.DateTimeFormat.FullDateTimePattern = "dd/MMM/YYYY";

    CultureInfo.DefaultThreadCurrentCulture = newCulture;
    CultureInfo.DefaultThreadCurrentUICulture = newCulture;

    Thread.CurrentThread.CurrentCulture = newCulture;
    Thread.CurrentThread.CurrentUICulture = newCulture;

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

        var lang = System.Windows.Markup.XmlLanguage.GetLanguage(newCulture.IetfLanguageTag);
        FrameworkContentElement.LanguageProperty.OverrideMetadata(
              typeof(System.Windows.Documents.TextElement),
              new FrameworkPropertyMetadata(lang)
            );
}

But it doesn't works

mm8
  • 163,881
  • 10
  • 57
  • 88
chincheta73
  • 187
  • 1
  • 22
  • Possible duplicate of [How to set and change the culture in WPF](https://stackoverflow.com/questions/4041197/how-to-set-and-change-the-culture-in-wpf) – Magnetron Jan 02 '18 at 16:27
  • 1
    It is not a duplicate of that question. My problem is that the label that shows the DateTime binding is not checking the DateTimeFormat patterns, or that my patterns are not set correctly. Also, my format should not be dependent of the current culture. – chincheta73 Jan 02 '18 at 16:54
  • Overriding things in the current `CultureInfo` is an absolutely horrible idea that may blow up somewhere completely unexpected. Not only you're mutating global variables, you are mutating *someone else's* global variables - in this case, the framework's. – Anton Tykhyy Jan 02 '18 at 17:18
  • Ok @AntonTykhyy Then how can ai accomplish this? – chincheta73 Jan 02 '18 at 17:31
  • Use a custom binding like @mm8 suggests below. – Anton Tykhyy Jan 02 '18 at 17:35
  • Ok. I wanted to avoid modifying every line where the DateTime is binded but if this is the better solution, I'll do that. – chincheta73 Jan 02 '18 at 17:39

2 Answers2

2

Is there any way to set the StringFormat for all DateTime objects globally independently of the CultureInfo in my WPF Application

A DateTime object doesn't have any StringFormat but a Binding has. You could create a custom Binding class:

public class MyCustomBinding : Binding
{
    public MyCustomBinding(string path)
        :base(path)
    {
        StringFormat = "yyyy-MM-dd";
    }
}

Usage:

<DataGridTextColumn Header="Date" Binding="{local:MyCustomBinding Date}"/>

Or you could set the Language property of the element:

<DataGrid x:Name="dg" Language="en">

You could also do this globally for all elements in your App.xaml.cs:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        var culture = new CultureInfo("en");
        FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), 
            new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(culture.IetfLanguageTag)));
    }
}
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Okey, I did set the language property for all elements in my App. But the format displayed now is dd/MMM/YYYY hh:ss:mm and I want to remove the hh:ss:mm part. Is there any way to do this globally? I don't want to edit each binding. – chincheta73 Jan 02 '18 at 17:13
  • Custom binding is the way to go - it's clear and declarative. Just call it something that will make the intent obvious, like `InvariantDateBinding`. – Anton Tykhyy Jan 02 '18 at 17:16
0

in app.xaml.cs

  public App()
        {            
          
            CultureInfo ci = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
            ci.DateTimeFormat.ShortDatePattern = "M/d/yyyy";
            Thread.CurrentThread.CurrentCulture = ci;
        }
jithu
  • 1,867
  • 1
  • 7
  • 16