我在周末一直致力于一个宠物项目,以了解有关C#的更多信息,并在使用本地化时遇到了一个奇怪的问题。更具体地说,我遇到的问题是System.Threading.Thread.CurrentThread.CurrentUICulture。
我已经设置了我的应用,以便用户可以通过单击菜单项快速更改应用的语言。菜单项依次在用户设置“语言”中保存语言的双字母代码(例如“en”,“fr”等),然后重新启动应用程序。
Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
Application.Restart();
启动应用程序时,Form的构造函数中的第一行代码(甚至在InitializeComponent()之前)从设置中获取语言字符串,并设置CurrentUICulture,如下所示:
public Form1()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
InitializeComponent();
}
问题是,这不能始终如一地发挥作用。有时,一切运行良好,应用程序根据保存在设置文件中的字符串加载正确的语言。其他时候,它没有,并且在重新启动应用程序后语言保持不变。
起初我认为在重新启动应用程序之前我没有保存语言,但绝对不是这样。如果无法加载正确的语言,如果我要关闭应用程序并再次运行它,则会正确显示正确的语言。所以这意味着语言字符串已被保存,但我的表单构造函数中的CurrentUICulture赋值有时没有效果。
有任何帮助吗?我是否缺少C#中的线程如何工作?这可能是特定于机器的,所以如果它有任何区别我会使用奔腾双核CPU。
更新
弗拉德让我检查CurrentThread的CurrentUICulture是什么。所以我在构造函数中添加了一个MessageBox,告诉我CurrentUICulture的双字母代码是什么,以及我的语言用户字符串的值。MessageBox.Show(string.Format("Current Language: {0}\nCurrent UI Culture: {1}", Properties.Settings.Default.Language, Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName));
加载错误的语言时,语言字符串和CurrentUICulture都使用错误的语言。所以我想CurrentUICulture已被清除,我的问题实际上是语言设置。
所以我想问题是我的应用程序有时加载以前保存的语言字符串而不是最后保存的语言字符串。如果重新启动应用程序,它将加载实际保存的语言字符串。
答案 0 :(得分:3)
我遇到了同样的问题。我发现Application.Restart()并没有真正重启,请参阅MSDN。
因此,Application.Restart()不会在表单构造函数中调用初始化事物 比如InitializeComponent(),更多的是“应用程序在它们最初运行的上下文中重新启动。”
所以你的代码是正确的
Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
public Form1()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
//...
InitializeComponent();
}
但Application.Restart()
无效。如果您关闭应用程序并再次打开它,则会执行(新)设置。
因此,我们必须找到一种方法来再次初始化表单,以便进行新的语言设置。
答案 1 :(得分:1)
你能检查一下你的主题CurrentUICulture
是什么吗?
我记得像你这样的问题;它是通过重新加载包含要本地化的字符串的资源字典来解决的:
Thread.CurrentThread.CurrentUICulture = <new culture>;
ResourceDictionary newDict = new ResourceDictionary();
newDict.Source = localizedStrings.Source;
localizedStrings = newDict;
(这种方法也是动态的; here是更多信息。)
答案 2 :(得分:1)
您可以手动更改当前表单的语言,类似于:
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;
希望有所帮助!
答案 3 :(得分:0)
您可以通过关闭打开的表单并重新创建它们来简单地“重置”您的应用程序。然后,您可以在用户更改设置时直接设置文化。
此外,尝试提供一些调试输出,以便您了解正在设置的值以及文化是否真正符合您的期望。
编辑:我的猜测:由于必须将数据写入文件,然后从该文件加载,因此可能重新启动太快而无法完成写入。
答案 4 :(得分:0)
通过使用CurrentThread.CurrentUICulture,然后更改表单,您无需重新启动应用程序。请参阅我的旧帖子here