178

アプリケーション全体のカルチャを設定する方法はありますか? すべての現在のスレッドと新しいスレッド?

カルチャの名前がデータベースに保存されており、アプリケーションの起動時に実行します

CultureInfo ci = new CultureInfo(theCultureString);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;

しかし、もちろん、新しいスレッドで何かをしたい場合、これは「失われます」。それを設定する方法とアプリケーション全体の方法はありCurrentCultureますCurrentUICultureか? 新しいスレッドもその文化を得るのですか?それとも、接続できる新しいスレッドが作成されるたびに発生するイベントですか?

4

10 に答える 10

201

.NET 4.5 では、CultureInfo.DefaultThreadCurrentCultureプロパティを使用して AppDomain のカルチャを変更できます。

4.5 より前のバージョンでは、リフレクションを使用して AppDomain のカルチャを操作する必要があります。CultureInfo( m_userDefaultCulture.NET 2.0 mscorlib ではs_userDefaultCulture、.NET 4.0 mscorlib では) にプライベートな静的フィールドがありCurrentCulture、スレッドがそれ自体にそのプロパティを設定していない場合に返されるものを制御します。

これはネイティブ スレッド ロケールを変更しないため、この方法でカルチャを変更するコードを出荷することはおそらくお勧めできません。ただし、テストには役立つ場合があります。

于 2011-09-24T00:25:59.320 に答える
36

これはよく聞かれます。基本的に、.NET 4.0 にはありません。新しいスレッド (またはThreadPool関数) の開始時に手動で行う必要があります。カルチャ名 (または単にカルチャ オブジェクト) を静的フィールドに格納して、DB にアクセスする手間を省くことができますが、それだけです。

于 2009-01-22T11:43:01.913 に答える
19

リソースを使用している場合は、次の方法で手動で強制できます。

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 のように言語コードを入力できます。言語コードの完全なリストについては、言語識別子とロケールを参照してください。

于 2011-11-08T01:01:37.507 に答える
6

実際には、デフォルトのスレッド カルチャと 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 ではなくなり、代わりに、ShortTimePattern の地域設定を尊重するように私の小さなハックで完全な en-AU になりました。

万歳、万事順調です!か否か。Convert メソッドに渡されるカルチャ パラメーターは、依然としてen-US です。ええと、なんと!? しかし、それは始まりです。せめてこの先

  • アプリの読み込み時に UI カルチャを一度修正できます
  • から常にアクセスできますCultureInfo.CurrentUICulture
  • string.Format("{0}", DateTime.Now)カスタマイズされた地域設定が使用されます

フレームワークのバージョン 4.5 を使用できない場合は、CurrentUICulture を CultureInfo の静的プロパティとして設定することをあきらめ、独自のクラスの 1 つの静的プロパティとして設定します。これは、string.Format の既定の動作を修正したり、バインディングで StringFormat を適切に機能させたりしません。その後、アプリの論理ツリーをたどって、アプリ内のすべてのバインディングを再作成し、コンバーター カルチャを設定します。

于 2013-01-17T05:19:42.603 に答える
3

DefaultThreadCurrentCultureフレームワーク 4.0にDefaultThreadCurrentUICultureも存在しますが、プライベートです。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
于 2015-01-20T09:44:50.787 に答える
3

この回答は、@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
        }
    }
}
于 2017-08-16T05:39:45.307 に答える
3

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")
    }
});

詳細については、次の一連のブログ記事をご覧ください。

于 2016-03-07T11:28:43.210 に答える
2

すべてのスレッドとウィンドウに CultureInfo を設定する実用的なソリューション。

  1. App.xamlファイルを開き、新しい "Startup" 属性を追加して、アプリのスタートアップ イベント ハンドラーを割り当てます。
<Application ........
             Startup="Application_Startup"
>
  1. App.xaml.csファイルを開き、このコードを作成したスタートアップ ハンドラー (この場合は Application_Startup) に追加します。クラス App は次のようになります。
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            CultureInfo cultureInfo = CultureInfo.GetCultureInfo("en-US");
            System.Globalization.CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
            System.Globalization.CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
            Thread.CurrentThread.CurrentCulture = cultureInfo;
            Thread.CurrentThread.CurrentUICulture = cultureInfo;
        }
    }
于 2020-04-21T11:11:47.187 に答える