Setting CurrentCulture and CurrentUICulture of an application

Is there a way of setting culture for a whole application? All current threads and new threads?

We have the name of the culture stored in a database, and when our application starts, we do

CultureInfo ci = new CultureInfo(theCultureString);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;

But, of course, this gets “lost” when we want to do something in a new thread. Is there a way of setting that CurrentCulture and CurrentUICulture for the whole application? So that new threads also gets that culture? Or is it some event fired whenever a new thread is created that I can hook up to?

Difference between CurrentCulture, InvariantCulture, CurrentUICulture and InstalledUICulture

What is the difference between CurrentCulture, InvariantCulture, CurrentUICulture and InstalledUICulture from System.Globalization.CultureInfo?



Determine CurrentCulture and CurrentUICulture for an arbitrary HttpContext

Given an instance of an HttpContext object, is there a way to determine the CurrentCulture and/or CurrentUICulture for the thread it is executing on? Or more generally, is there a way to gain access t

How to set Silverlight CurrentUICulture/CurrentCulture correctly?

I’m working on a SL5 app with C# and I’m looking to internationalize it. I found the following to set the UI culture: var culture = new CultureInfo(Thread.CurrentThread.CurrentUICulture.TwoLetterISOLa

What is the difference between CurrentCulture and CurrentUICulture properties of CultureInfo in .NET?

In .NET there is the CultureInfo class in the System.Globalization namespace. It has two similar properties both returning values of the CultureInfo type: CurrentCulture and CurrentUICulture. What is

Why are CurrentCulture and CurrentUICulture different?

I’ve got a Silverlight application and corresponding ASP.Net application hosting it. I want to use the detected culture settings to format dates in the Silverlight application but I don’t think it’s

Setting CurrentUICulture is not being remembered by my application

I have an asp.net mvc application where i want the user to be able to change language. I have provided a series of links with small flags on to let the user choose language. The target of all these li

How to prevent Thread.CurrentThread.CurrentCulture to switch to the default browser value after setting it manually?

In my current application I want to implement ASP.Net localization with global resources. I have the problem, that after changing the CurrentThread.CurrentUICulture and CurrentThread.CurrentCulture an

Resource file for en-GB locale doesn’t load in C# application

I am setting the locale of my application using Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(en-GB); Thread.CurrentThread.CurrentUICulture = new System.Globalization.Cu

How to update Window form UI after setting CurrentUICulture?

I tried to set CurrentUICulture of the application at run time. However, the menu items in my forms remained unchanged. Do I have to do something additional to changing CurrentUICulture?

Easy way to set CurrentCulture for the entire application?

In a .net 2 winforms application, what’s a good way to set the culture for the entire application? Setting CurrentThread.CurrentCulture for every new thread is repetitive and error-prone. Ideally I’d

Answers

This gets asked a lot. Basically, no there isn’t. You have to do it manually at the start of each new thread (or ThreadPool function). You could perhaps store the culture name (or just the culture object) in a static field to save having to hit the DB, but that it about it.

In .NET 4.5, you can use the CultureInfo.DefaultThreadCurrentCulture property to change the culture of an AppDomain.

For versions prior to 4.5 you have to use reflection to manipulate the culture of an AppDomain. There is a private static field on CultureInfo (m_userDefaultCulture in .NET 2.0 mscorlib, s_userDefaultCulture in .NET 4.0 mscorlib) that controls what CurrentCulture returns if a thread has not set that property on itself.

This does not change the native thread locale and it is probably not a good idea to ship code that changes the culture this way. It may be useful for testing though.

If you are using resources, you can manually force it by:

Resource1.Culture = new System.Globalization.CultureInfo("fr"); 

In the resource manager, there is an auto generated code that is as follows:

/// <summary>
///   Overrides the current thread's CurrentUICulture property for all
///   resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
    get {
        return resourceCulture;
    }
    set {
        resourceCulture = value;
    }
}

Now every time you refer to your individual string within this resource, it overrides the culture (thread or process) with the specified resourceCulture.

You can either specify language as in “fr”, “de” etc. or put the language code as in 0x0409 for en-US or 0x0410 for it-IT. For a full list of language codes please refer to: Language Identifiers and Locales

As previously mentioned this can be done via reflection. If anyone wants an example and explanation of how to do this in reflection see this link: http://blog.rastating.com/setting-default-currentculture-in-all-versions-of-net/

Actually you can set the default thread culture and UI culture, but only with Framework 4.5+

I put in this static constructor

static MainWindow()
{
  CultureInfo culture = CultureInfo
    .CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
  var dtf = culture.DateTimeFormat;
  dtf.ShortTimePattern = (string)Microsoft.Win32.Registry.GetValue(
    "HKEY_CURRENT_USER//Control Panel//International", "sShortTime", "hh:mm tt");
  CultureInfo.DefaultThreadCurrentUICulture = culture;
}

and put a breakpoint in the Convert method of a ValueConverter to see what arrived at the other end. CultureInfo.CurrentUICulture ceased to be en-US and became instead en-AU complete with my little hack to make it respect regional settings for ShortTimePattern.

Hurrah, all is well in the world! Or not. The culture parameter passed to the Convert method is still en-US. Erm, WTF?! But it’s a start. At least this way

  • you can fix the UI culture once when your app loads
  • it’s always accessible from CultureInfo.CurrentUICulture
  • string.Format(“{0}”, DateTime.Now) will use your customised regional settings

If you can’t use version 4.5 of the framework then give up on setting CurrentUICulture as a static property of CultureInfo and set it as a static property of one of your own classes. This won’t fix default behaviour of string.Format or make StringFormat work properly in bindings then walk your app’s logical tree to recreate all the bindings in your app and set their converter culture.

DefaultThreadCurrentCulture and DefaultThreadCurrentUICulture are present in Framework 4.0 too, but they are Private. Using Reflection you can easily set them. It affects all threds where CurrentCulture is not explicitly set (running threads too).

Public Sub SetDefaultThreadCurrentCulture(paCulture As CultureInfo)
    Thread.CurrentThread.CurrentCulture.GetType().GetProperty("DefaultThreadCurrentCulture").SetValue(Thread.CurrentThread.CurrentCulture, paCulture, Nothing)
    Thread.CurrentThread.CurrentCulture.GetType().GetProperty("DefaultThreadCurrentUICulture").SetValue(Thread.CurrentThread.CurrentCulture, paCulture, Nothing)
End Sub

For ASP.NET5, i.e. ASPNETCORE, you can do the following in configure:

app.UseRequestLocalization(new RequestLocalizationOptions
{
    DefaultRequestCulture = new RequestCulture(new CultureInfo("en-gb")),
    SupportedCultures = new List<CultureInfo>
    {
        new CultureInfo("en-gb")
    },
            SupportedUICultures = new List<CultureInfo>
    {
        new CultureInfo("en-gb")
    }
});

Here’s a series of blog posts that gives more information.

Here is the solution for c# MVC:

  1. First : Create a custom attribute and override method like this:

    public class CultureAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Retreive culture from GET
            string currentCulture = filterContext.HttpContext.Request.QueryString["culture"];
    
            // Also, you can retreive culture from Cookie like this :
            //string currentCulture = filterContext.HttpContext.Request.Cookies["cookie"].Value;
    
            // Set culture
            Thread.CurrentThread.CurrentCulture = new CultureInfo(currentCulture);
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(currentCulture);
        }
    }
    
  2. Second : In App_Start, find FilterConfig.cs, add this attribute. (this works for WHOLE application)

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            // Add custom attribute here
            filters.Add(new CultureAttribute());
        }
    }    
    

That’s it !

If you want to define culture for each controller/action in stead of whole application, you can use this attribute like this:

[Culture]
public class StudentsController : Controller
{
}

Or:

[Culture]
public ActionResult Index()
{
    return View();
}

For .net 4.5 and higher you should use

var culture = new CultureInfo("en-US");
        CultureInfo.DefaultThreadCurrentCulture = culture;
        CultureInfo.DefaultThreadCurrentUICulture = culture;