アプリケーション全体にカルチャを設定する方法はありますか?現在のすべてのスレッドと新しいスレッド?
カルチャの名前はデータベースに保存されており、アプリケーションの起動時に
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
(.NET 2.0 mscorlibのm_userDefaultCulture
、. NET 4.0 mscorlibのs_userDefaultCulture
)には、静的プロパティがあり、スレッドがそのプロパティを設定していない場合にCurrentCulture
が返すものを制御します。
これは、ネイティブスレッドのロケールを変更するものではありません。おそらく、この方法でカルチャを変更するコードを出荷することはお勧めできません。ただし、テストには役立ちます。
これはよく聞かれます。基本的にはありません。NET4.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」、「de」などのように言語を指定するか、en-USの場合は0x0409、it-ITの場合は0x0410のように言語コードを入力できます。言語コードの完全なリストについては、以下を参照してください。 言語識別子とロケール
.net 4.5以降では、使用する必要があります
var culture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
実際にはcanデフォルトのスレッドカルチャと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メソッドに渡されるカルチャパラメータはstill en-USです。うーん、WTF ?!しかし、それは始まりです。少なくともこのように
CultureInfo.CurrentUICulture
から常にアクセス可能ですstring.Format("{0}", DateTime.Now)
は、カスタマイズされた地域設定を使用しますフレームワークのバージョン4.5を使用できない場合は、CurrentUICultureをCultureInfoの静的プロパティとして設定することをあきらめ、独自のクラスの1つの静的プロパティとして設定します。これは、string.Formatのデフォルトの動作を修正したり、バインディングでStringFormatを適切に動作させたりしてから、アプリの論理ツリーをたどってアプリ内のすべてのバインディングを再作成し、コンバーターカルチャを設定します。
この答えは、@ 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に存在しますが、プライベートです。 Reflectionを使用すると、簡単に設定できます。これは、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 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番目:App_StartでFilterConfig.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();
}