35

I have an application, which is based for India, and I'm setting Culture as:

Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-IN");

The above code is called before the Window.InitializeComponent() method is called.

Still this is showing $ as CurrencySymbol in all TextBoxes.

If I bind a TextBox as following, it shows Rs. as CurrencySymbol:

Text="{Binding Salary,Mode=TwoWay,StringFormat=C,ConvertCulture=en-IN}".
ASh
  • 34,632
  • 9
  • 60
  • 82
Varun Jain
  • 1,015
  • 2
  • 13
  • 19
  • Also keep this in mind: http://stackoverflow.com/questions/520115/stringformat-localization-problem/520334#520334 – Snowbear Sep 17 '11 at 10:29

6 Answers6

58

I think you will need to add the following.

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-IN");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-IN");
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(
            XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));

Read more here:

http://www.west-wind.com/weblog/posts/2009/Jun/14/WPF-Bindings-and-CurrentCulture-Formatting

Just to give you an example, this is how I initialize the Culture in my program, based on the user setting, but you can simply replace UserSettings.DefaultCulture and UserSettings.Default.UICultrue with your wanted Culture.

private static void InitializeCultures()
{
    if (!String.IsNullOrEmpty(UserSettings.Default.Culture))
    {
        Thread.CurrentThread.CurrentCulture = new CultureInfo(UserSettings.Default.Culture);
    }
    if (!String.IsNullOrEmpty(UserSettings.Default.UICulture))
    {
        Thread.CurrentThread.CurrentUICulture = new CultureInfo(UserSettings.Default.UICulture);
    }

    FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(
        XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
}
Flat Eric
  • 7,971
  • 9
  • 36
  • 45
eandersson
  • 25,781
  • 8
  • 89
  • 110
  • 1
    Thanks. I was missing the following line of code. FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata( XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag))); What actually this code do? – Varun Jain Sep 17 '11 at 10:37
  • 1
    Take a look at the article I included, it includes a pretty good description of the issue. http://www.west-wind.com/weblog/posts/2009/Jun/14/WPF-Bindings-and-CurrentCulture-Formatting – eandersson Sep 17 '11 at 10:40
  • 3
    Using `CultureInfo.CurrentCulture.IetfLanguageTag` always uses Microsofts default values for the given culture and completely ignores changes made by the user. For example here in Germany default date format is 'dd.mm.yyyy' but I manually configured this to be ISO 8601 compliant: 'yyyy-mm-dd' but this is ignored within WPF apps most of the time (some special controls like xceeds Grid behave different/smarter). – springy76 Sep 17 '11 at 22:36
  • 11
    Please note that the `CultureInfo.CurrentCulture.IetfLanguageTag` is deprecated: _"This property and the GetCultureInfoByIetfLanguageTag method are deprecated. Instead, you should use a the CultureInfo.Name property. IETF tags and names are identical."_. You should probably use `CultureInfo.Name` instead as indicated. – Jony Adamit Sep 17 '15 at 14:04
18

For me just works, if i put this code to the OnStartup overrided method:

public partial class App : Application
{
      public App()
      {                
      }

      protected override void OnStartup(StartupEventArgs e)
      {
          var vCulture = new CultureInfo("de-DE");

          Thread.CurrentThread.CurrentCulture = vCulture;
          Thread.CurrentThread.CurrentUICulture = vCulture;
          CultureInfo.DefaultThreadCurrentCulture = vCulture;
          CultureInfo.DefaultThreadCurrentUICulture = vCulture;

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

          base.OnStartup(e);
      }
}
Esteban Verbel
  • 738
  • 2
  • 20
  • 39
Bence Végert
  • 728
  • 10
  • 12
  • And whats happen if i force en-US culture to the whole appliction, and my application run n a machine configured in spanish or any other culture not is en-US? – MrBi Jun 21 '22 at 05:47
  • What you mean? The operating system language no make sense in this meaning. If you set en-US for the application, it stays and should run finely. – Bence Végert Jun 22 '22 at 07:17
3
Thread.CurrentThread.CurrentCulture = 
    System.Globalization.CultureInfo.GetCultureInfo("en-IN");

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

This will switch the default language for the entire application. You’ll want to use this only in startup code as this setting can be applied only once per application. You can still override individual forms when necessary as below

this.Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag);

All WPF elements include a Language property that can be assigned and determines the Culture that is used for formatting.

Reference

CharithJ
  • 46,289
  • 20
  • 116
  • 131
2

To me just this worked, but in order to solve ToString and to make it work over the entire app, it's important to add it in constructor, not OnStartup etc, before you set up service container etc. otherwise it doesn't work in subsequent threads and CultureInfo.CurrentUICulture still resolves to the default system CultureInfo.

public class App : Application
{
  public App() 
  {     
    var culture = new CultureInfo("en-IN");
    CultureInfo.DefaultThreadCurrentCulture = culture;
    CultureInfo.DefaultThreadCurrentUICulture = culture;

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

     // should be before all this
     var host = Host
       .CreateDefaultBuilder()
       .ConfigureServices(ConfigureServices)
       ...;        
  }
}
Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
0

For my datagrid data i used below lines of code in App.xaml.cs & it worked .. for de it displayed dot and En it displayed comma for 4 digit numbers.

FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(
            
XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
Chris Catignani
  • 5,040
  • 16
  • 42
  • 49
PPr
  • 81
  • 4
0

Also, there's another way of doing this, assuming that you're using a TextBlock:

<TextBlock Text="{Binding Salary, Mode=TwoWay, StringFormat='{}{0:C}', ConverterCulture='en-IN'}" />

Please bear in mind the single quotes are needed.

Gabriel Marius Popescu
  • 2,016
  • 2
  • 20
  • 22