是否有一个整体的应用程序设置文化的一种方式?目前所有的线程和新主题?
我们有存储在数据库中文化的名字,和我们的应用程序启动时,我们做
CultureInfo ci = new CultureInfo(theCultureString);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
但是,当然,这个被“丢失”当我们想要做的东西在一个新的线程。是否有设置,CurrentCulture
和CurrentUICulture
整个应用程序的方法吗?这样新主题也得到这种文化?或者是一些事件,每当一个新的线程被创建,我可以钩到解雇?
在.NET 4.5中,您可以使用CultureInfo.DefaultThreadCurrentCulture
属性来更改一个AppDomain的文化。
对于之前的4.5版本中,你必须使用反射来操纵一个AppDomain的文化。有上CultureInfo
私有静态字段(m_userDefaultCulture
在.NET 2.0的mscorlib,s_userDefaultCulture
在.NET 4.0的mscorlib)控制,如果一个线程没有设置本身属性是什么CurrentCulture
返回。
这不会改变本地线程区域,它可能不是出货的代码,改变了文化的这样一个好主意。这可能是用于测试,但。
这个被问了很多。基本上,没有没有,不是.NET 4.0。你必须在每一个新的线程(或ThreadPool
功能)开始做手工。也许你可以在一个静态字段文化名(或只是培养对象)存储,省去打DB,但仅此而已。
如果您使用的资源,您可以手动迫使它通过:
Resource1.Culture = new System.Globalization.CultureInfo("fr");
在资源管理器中,有一个自动生成的代码如下:
/// <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;
}
}
现在,每次你参考您的个人的字符串在此资源内时,它会覆盖文化(线程或进程)使用指定resourceCulture。
您可以指定语言为“FR”,“德”等,或把语言代码为0x0409为EN-US或阿拉伯语 - 约旦它-IT。有关语言代码的完整列表,请参阅:Language Identifiers and Locales
对于.NET 4.5和更高的你应该使用
var culture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
其实你可以设置默认的线程文化和UI文化,但只有框架4.5+
我把这个静态构造函数
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;
}
将断点设置在ValueConverter的转换方法,看看在另一端是什么来了。 CultureInfo.CurrentUICulture不再是EN-美国,成为代替EN-AU完成我的小黑客,使之尊重区域设置ShortTimePattern。
华友世纪,一切都很好,在世界上!或不。传递给转换方法的文化参数仍然是EN-US。呃,WTF?但它是一个开始。至少这样
CultureInfo.CurrentUICulture
访问string.Format("{0}", DateTime.Now)
将使用您的自定义区域设置如果您无法使用该框架的4.5版本,那么放弃对设置的CurrentUICulture作为CultureInfo的静态属性并将其设置为自己的一个类的静态属性。这不会解决的String.format的默认行为或使绑定的StringFormat正常工作,然后走你的应用程序的逻辑树重新创建你的应用程序中的所有绑定,并设置其转换的文化。
对于ASP.NET5,即ASPNETCORE,你可以做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")
}
});
下面是提供了更多的信息series of blog posts。
这个答案是有点扩张@ rastating最伟大的答案。您可以使用.NET的所有版本的下面的代码没有任何后顾之忧:
public static void SetDefaultCulture(CultureInfo culture)
{
Type type = typeof (CultureInfo);
try
{
// Class "ReflectionContext" exists from .NET 4.5 onwards.
if (Type.GetType("System.Reflection.ReflectionContext", false) != null)
{
type.GetProperty("DefaultThreadCurrentCulture")
.SetValue(System.Threading.Thread.CurrentThread.CurrentCulture,
culture, null);
type.GetProperty("DefaultThreadCurrentUICulture")
.SetValue(System.Threading.Thread.CurrentThread.CurrentCulture,
culture, null);
}
else //.NET 4 and lower
{
type.InvokeMember("s_userDefaultCulture",
BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
null,
culture,
new object[] {culture});
type.InvokeMember("s_userDefaultUICulture",
BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
null,
culture,
new object[] {culture});
type.InvokeMember("m_userDefaultCulture",
BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
null,
culture,
new object[] {culture});
type.InvokeMember("m_userDefaultUICulture",
BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
null,
culture,
new object[] {culture});
}
}
catch
{
// ignored
}
}
}
DefaultThreadCurrentCulture
和DefaultThreadCurrentUICulture
存在于Framework 4.0中也一样,但它们是私有的。使用反射,你可以轻松地进行设置。这将影响地方CurrentCulture
未明确设置的所有线程(正在运行的线程太)。
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
下面是C#MVC的解决方案:
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);
}
}
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
// Add custom attribute here
filters.Add(new CultureAttribute());
}
}
而已 !
如果你想将文化定义为整个应用程序的每个代替控制器/动作,你可以使用这样该属性:
[Culture]
public class StudentsController : Controller
{
}
要么:
[Culture]
public ActionResult Index()
{
return View();
}