绅士的斑马 · 【QT】子类化QThread实现多线程 - ...· 1 月前 · |
酷酷的橙子 · SetWindowsHookExW 函数 ...· 2 周前 · |
激动的烤地瓜 · 配置虚拟网络 - 高级层 Azure ...· 3 月前 · |
谈吐大方的镜子 · SpringBoot中@ComponentS ...· 7 月前 · |
忧郁的路灯 · 导出服务器身份验证证书的私钥部分 | ...· 11 月前 · |
老实的香菇 · NASA的GLDAS数据预处理_gldas数 ...· 1 年前 · |
豪情万千的花生 · 2023年最全Python资料合集(电子书+ ...· 1 年前 · |
有没有一种为整个应用设置文化的方法?所有当前线程和新线程-
我们有存储在数据库中的区域性的名称,当应用程序启动时,我们这样做
CultureInfo ci = new CultureInfo(theCultureString);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
但是,当然,当我们想要在一个新线程中做一些事情时,这就会“丢失”。有没有办法为整个应用程序设置
CurrentCulture
和
CurrentUICulture
?所以新的线程也会得到这种区域性吗?或者,它是在创建新线程时触发的某个事件,我可以连接到该线程吗?
这个问题被问得很多。基本上,没有,不是针对.NET 4.0。您必须在每个新线程(或
ThreadPool
函数)开始时手动执行此操作。您也许可以将区域性名称(或仅区域性对象)存储在静态字段中,以避免访问DB,但仅此而已。
在.NET 4.5中,可以使用
CultureInfo.DefaultThreadCurrentCulture
属性更改AppDomain的区域性。
对于4.5之前的版本,您必须使用反射来操作AppDomain的区域性。在
CultureInfo
上有一个私有的静态字段( .NET 2.0mcorlib中的
m_userDefaultCulture
,.NET 4.0mcorlib中的
s_userDefaultCulture
),它控制如果线程没有在自身上设置该属性,
CurrentCulture
将返回什么。
这不会更改本机线程区域设置,而且以这种方式发布更改区域性的代码可能不是一个好主意。不过,它可能对测试很有用。
如果您正在使用资源,您可以通过以下方式手动强制执行:
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“、"de”等,或者将语言代码设置为0x0409表示en-US或0x0410表示it-IT。有关语言代码的完整列表,请访问: Language Identifiers and Locales
实际上,您可以设置默认的线程区域性和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的Convert方法中设置断点,以查看到达另一端的内容。CultureInfo.CurrentUICulture不再是en-US,取而代之的是en-AU,通过我的小技巧使它尊重ShortTimePattern的区域设置。
万岁,人间万事如意!或者不是。传递给Convert方法的区域性参数仍为en-US。呃,见鬼?!但这只是个开始。至少是这样的
CultureInfo.CurrentUICulture
string.Format("{0}", DateTime.Now)
访问
如果您不能使用该框架的4.5版,那么放弃将CurrentUICulture设置为CultureInfo的静态属性,并将其设置为您自己的类的静态属性。这不会修复string.Format的默认行为,也不会让StringFormat在绑定中正常工作,然后遍历应用程序的逻辑树来重新创建应用程序中的所有绑定,并设置它们的转换器文化。
DefaultThreadCurrentCulture
和
DefaultThreadCurrentUICulture
也出现在Framework4.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
对于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的解决方案:
public CultureAttribute : filterContext.HttpContext.Request.Cookies"cookie".Value;{ public override void (ActionExecutingContext filterContext) { //从GET string中检索区域性currentCulture = CultureInfo.CreateSpecificCulture(currentCulture);//您还可以像这样从Cookie中检索区域性: //string CultureAttribute= ActionFilterAttribute //设置区域性Thread.CurrentThread.CurrentCulture = CultureInfo( currentCulture );Thread.CurrentThread.CurrentUICulture =Cookie} }
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { //在此处添加自定义属性filters.Add(new CultureAttribute());}}
就是这样!
如果你想为每个控制器/动作定义区域性,而不是整个应用程序,你可以像这样使用这个属性:
[Culture]
public class StudentsController : Controller
}
或者:
[Culture]
public ActionResult Index()
return View();
}
对于.NET 4.5和更高版本,您应该使用:
var culture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
这个答案是对@rastating的伟大答案的一点扩展。您可以在所有版本的.NET中使用以下代码,无需担心:
public static void SetDefaultCulture(CultureInfo culture)
Type type = typeof (CultureInfo);
// 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
}
为所有线程和窗口设置CultureInfo的工作解决方案。
<Application ........
Startup="Application_Startup"
>
public partial class App : Application
private void Application_Startup(object sender, StartupEventArgs e)
CultureInfo cultureInfo = CultureInfo.GetCultureInfo("en-US");
绅士的斑马 · 【QT】子类化QThread实现多线程 - 李春港 1 月前 |