thread.currentthread.currentuicultureは一貫して機能しません
-
02-10-2019 - |
質問
私は週末にPETプロジェクトに取り組んでC#の詳細を学び、ローカリゼーションで作業する際に奇妙な問題に遭遇しました。より具体的には、私が抱えている問題はsystem.threading.thread.currentthread.currentuicultureにあります。
ユーザーがメニュー項目をクリックしてアプリの言語をすばやく変更できるように、アプリをセットアップしました。メニュー項目は、「言語」と呼ばれるユーザー設定で言語の2文字のコード(「en」、「fr」など)を保存し、アプリケーションを再起動します。
Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
Application.Restart();
アプリケーションが起動すると、フォームのコンストラクターのコードの最初の行(initializeComponent()の前であっても)は、設定から言語文字列を取得し、次のように現在の培養を設定します。
public Form1()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
InitializeComponent();
}
問題は、これは一貫して機能しないということです。すべてがうまく機能し、アプリケーションが設定ファイルに保存された文字列に基づいて正しい言語をロードする場合があります。それ以外の場合、それはそうではなく、アプリケーションが再起動された後も言語は同じままです。
最初は、アプリケーションを再起動する前に言語を保存しなかったと思っていましたが、それは間違いなくそうではありません。正しい言語がロードされない場合、アプリケーションを閉じて再度実行する場合、正しい言語が正しく表示されます。したがって、これは言語文字列が保存されていることを意味しますが、私のフォームコンストラクターの現在の培養の割り当ては時々効果がありません。
何か助けがありますか? C#でスレッドがどのように機能するかについて私が欠けていることはありますか?これは機械固有の可能性があるため、違いがある場合は、Pentium dual Core CPUを使用しています。
アップデート
Vladは、CurrentThreadのCurrentuicultureとは何かを確認するように頼みました。そこで、コンストラクターにメッセージボックスを追加して、CurrentUiculture Two-Letterコードと言語ユーザー文字列の値を教えてくれました。
MessageBox.Show(string.Format("Current Language: {0}\nCurrent UI Culture: {1}", Properties.Settings.Default.Language, Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName));
間違った言語が読み込まれると、言語文字列と現在の文化栽培の両方が間違った言語を持っています。したがって、現在の養殖がクリアされており、私の問題は実際に言語設定にあると思います。
ですから、問題は私のアプリケーションだと思います 時折 最後に保存された言語文字列ではなく、以前に保存した言語文字列をロードします。アプリが再起動された場合、実際に保存された言語文字列がロードされます。
解決
同じ問題が発生しました。 Application.restart()が実際には絶対に再起動していないことがわかりました。 MSDN.
したがって、application.restart()は、firtionizecomponent()のようなフォームコンストラクター内の初期化されたものを呼び出さないでください。「アプリケーションは、最初に実行されたコンテキストで再起動されます」。
したがって、あなたのコードは正しいです
Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
public Form1()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
//...
InitializeComponent();
}
しかし、それはこのように機能しません Application.Restart()
. 。アプリを閉じて再度開くと、(新しい)設定が取得されます。
そのため、新しい言語設定を実現するために、フォームを再度初期化する方法を見つけなければなりません。
他のヒント
あなたのスレッドが何であるかを確認していただけませんか CurrentUICulture
?
私はあなたのような問題を抱えていたことを覚えています。ローカライズされる文字列を含むリソース辞書をリロードすることで解決されました。
Thread.CurrentThread.CurrentUICulture = <new culture>;
ResourceDictionary newDict = new ResourceDictionary();
newDict.Source = localizedStrings.Source;
localizedStrings = newDict;
(そして、このアプローチも動的に機能しました。 ここ いくつかの情報です)。
これに似た現在のフォームの言語を手動で変更できます。
CultureInfo cInfo = new CultureInfo("en-US");
ResourceManager rm = new ResourceManager(GetType());
// For each control on the form, perform the translation manually (probably better in a loop)
control1.Text = rm.GetString(control1.Name + ".Text", cInfo);
// Now set the culture for all other dialogs
Thread.CurrentThread.CurrentUICulture = cInfo;
それが役立つことを願っています!
オープンフォームを閉じて再作成することにより、単にアプリケーションを「リセット」できます。次に、ユーザーが設定を変更したときに文化を直接設定できます。
また、デバッグ出力を提供して、どの値が設定されているか、文化が実際に期待しているものであるかどうかを確認してください。
編集:私の推測:データをファイルに書き込み、そのファイルから読み込む必要があるため、書き込みが完了するには速すぎる場合があります。
currentThread.CurrentUicultureを使用してからフォームを変更することにより、アプリケーションを再起動する必要はありません。私の古い投稿を参照してください ここ