有没有办法为整个应用程序设置文化?所有当前线程和新线程?

Svi*_*ish 173 c# multithreading cultureinfo

有没有办法为整个应用程序设置文化?所有当前线程和新线程?

我们将文化的名称存储在数据库中,当我们的应用程序启动时,我们就会这样做

CultureInfo ci = new CultureInfo(theCultureString);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
Run Code Online (Sandbox Code Playgroud)

但是,当然,当我们想要在新线程中做某事时,这会"丢失".有没有办法设置CurrentCultureCurrentUICulture整个应用程序?那么新线程也会获得这种文化?或者,只要创建了一个我可以连接的新线程,就会触发某个事件?

Aus*_*tin 190

在.NET 4.5中,您可以使用该CultureInfo.DefaultThreadCurrentCulture属性更改AppDomain的文化.

对于4.5之前的版本,您必须使用反射来操纵AppDomain的文化.在CultureInfo(m_userDefaultCulture在.NET 4.0 mscorlib中,s_userDefaultCulture在.NET 4.0 mscorlib中)有一个私有静态字段,它控制CurrentCulture在线程未在其自身上设置该属性时返回的内容.

这不会更改本机线程区域设置,并且发布以这种方式更改文化的代码可能不是一个好主意.但它可能对测试很有用.

  • 在ASP.NET应用程序中要小心此设置.在AppDomain上设置文化将为所有用户设置文化.因此,对于英语用户来说,以德语浏览网站并不是一件好事. (8认同)
  • 我继承了一个 ASP.NET 应用程序,它只有在所有文化都在美国时才有效。在这种情况下,此设置非常适合修复该缺陷之前的时间 (2认同)

Mar*_*ell 36

这问得很多.基本上,没有,不适用于.NET 4.0.您必须在每个新线程(或ThreadPool函数)的开头手动执行此操作.您可以将文化名称(或文化对象)存储在静态字段中,以节省必须访问数据库,但这就是它.

  • 这真的很烦人:(如果有一种方法可以自动为您的应用程序设置Current(UI)文化并让所有新线程获得该值,那将会很好. (7认同)
  • 谁说有关于解决方法的事情?这是怎么回事...... (2认同)
  • 在我们的应用程序中,我尝试“捕获”线程(通过从某些地方调用特殊方法)并将它们存储在一个集合中供以后使用(在这种情况下设置文化),这似乎工作得很远。 (2认同)

Rez*_*a S 18

如果您正在使用资源,可以通过以下方式手动强制它:

Resource1.Culture = new System.Globalization.CultureInfo("fr"); 
Run Code Online (Sandbox Code Playgroud)

在资源管理器中,有一个自动生成的代码如下:

/// <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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,每次在此资源中引用单个字符串时,它都会使用指定的resourceCulture覆盖文化(线程或进程).

您可以指定"fr","de"等语言,也可以将语言代码设置为en-US的0x0409或it-IT的0x0410.有关语言代码的完整列表,请参阅:语言标识符和语言环境


And*_*eas 7

对于.net 4.5及更高版本,您应该使用

var culture = new CultureInfo("en-US");
        CultureInfo.DefaultThreadCurrentCulture = culture;
        CultureInfo.DefaultThreadCurrentUICulture = culture;
Run Code Online (Sandbox Code Playgroud)


Pet*_*one 5

实际上,您可以设置默认的线程文化和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;
}
Run Code Online (Sandbox Code Playgroud)

并将断点放在ValueConverter的Convert方法中以查看到达另一端的内容。CultureInfo.CurrentUICulture不再是美国的,而是通过我的小技巧变成en-AU的完整版,以使其尊重ShortTimePattern的区域设置。

呼啦,世界上一切都很好!或不。传递给Convert方法的区域性参数仍为 en-US。恩,WTF ?!但这是一个开始。至少这样

  • 您可以在应用加载后修复一次UI文化
  • 它总是可以从 CultureInfo.CurrentUICulture
  • string.Format("{0}", DateTime.Now) 将使用您自定义的区域设置

如果您不能使用框架的版本4.5,则放弃将CurrentUICulture设置为CultureInfo的静态属性,并将其设置为您自己的类之一的静态属性。这将无法修复string.Format的默认行为,也无法使StringFormat在绑定中正常工作,然后遍历应用程序的逻辑树以重新创建应用程序中的所有绑定并设置其转换器区域性。