有没有为整个应用程序设置文化的方法? 所有当前线程和新线程?
有没有为整个应用程序设置文化的方法? 所有当前线程和新线程?
我们有存储在数据库中的文化的名称,当我们的应用程序启动时,我们做
CultureInfo ci = new CultureInfo(theCultureString); Thread.CurrentThread.CurrentCulture = ci; Thread.CurrentThread.CurrentUICulture = ci;
但是,当然,当我们想要在新线程中做某些事情时,这会“失去”。 有没有为整个应用程序设置CurrentCulture
和CurrentUICulture
的方法? 所以新线程也能获得这种文化? 或者,当一个新的线程被创build,我可以连接到一些事件触发?
在.NET 4.5中,可以使用CultureInfo.DefaultThreadCurrentCulture
属性来更改AppDomain的区域性。
对于4.5之前的版本,您必须使用reflection来操纵AppDomain的区域性。 CultureInfo
上有一个私有静态字段(.NET 2.0 mscorlib中的s_userDefaultCulture
,.NET 4.0 mscorlib中的s_userDefaultCulture
),用于控制CurrentCulture
在线程尚未设置属性时返回的内容。
这不会改变本地线程语言环境,并且可能不是一个好主意,以这种方式发布改变文化的代码。 尽pipe这可能对testing有用。
这被问了很多。 基本上,没有,没有.NET 4.0。 您必须在每个新线程(或ThreadPool
函数)开始时手动执行此操作。 你也许可以将文化名称(或文化对象)存储在一个静态字段中,以保存不必要的数据库,但这就是它。
如果您正在使用资源,则可以通过以下方式手动强制执行:
Resource1.Culture = new System.Globalization.CultureInfo("fr");
在资源pipe理器中,有一个自动生成的代码,如下所示:
/// <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; } }
现在,每当您在此资源中引用您的单个string时,它都将使用指定的resourceCulture覆盖文化(线索或进程)。
您可以按照“fr”,“de”等指定语言,也可以将语言代码置于en-US的0x0409或it-IT的0x0410。 有关语言代码的完整列表,请参阅: 语言标识符和语言环境
其实你可以设置默认的线程文化和UI文化,但只能使用Framework 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的Convert方法中放置一个断点,以查看到达另一端的内容。 CultureInfo.CurrentUICulture不再是en-US,而是变成en-AU,用我的小黑客来完成,使它符合ShortTimePattern的区域设置。
华友世界,一切都好! 或不。 传递给Convert方法的文化参数仍然是en-US。 恩,跆拳道? 但这是一个开始。 至less这样
- 当您的应用程序加载时,您可以修复一次UI文化
- 它始终可以从
CultureInfo.CurrentUICulture
访问 -
string.Format("{0}", DateTime.Now)
将使用您的自定义区域设置
如果你不能使用框架的4.5版本,那就放弃将CurrentUICulture设置为CultureInfo的一个静态属性,并将它设置为你自己类的静态属性。 这不会修复string.Format的默认行为,或使StringFormat在绑定中正常工作,然后遍历应用程序的逻辑树,以重新创build应用程序中的所有绑定并设置其转换器区域性。
对于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") } });
以下是一系列博客文章 ,提供更多信息。
这里是C#MVC的解决scheme:
-
首先:创build一个自定义属性并覆盖像这样的方法:
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); } }
-
其次:在App_Start中,findFilterConfig.cs,添加这个属性。 (这适用于整个应用程序)
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(); }
DefaultThreadCurrentCulture和DefaultThreadCurrentUICulture也存在于Framework 4.0中,但它们是私有的。 使用reflection,您可以轻松地设置它们。 它会影响CurrentCulture没有显式设置的所有Thred(运行线程)。
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
这个答案对于@ 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 } } }
对于.net 4.5及更高版本,您应该使用
var culture = new CultureInfo("en-US"); CultureInfo.DefaultThreadCurrentCulture = culture; CultureInfo.DefaultThreadCurrentUICulture = culture;