0

周末我一直在从事一个宠物项目,以了解有关 C# 的更多信息,并且在使用本地化时遇到了一个奇怪的问题。更具体地说,我遇到的问题是 System.Threading.Thread.CurrentThread.CurrentUICulture。

我已经设置了我的应用程序,以便用户可以通过单击菜单项来快速更改应用程序的语言。菜单项依次将语言的两个字母代码(例如“en”、“fr”等)保存在名为“Language”的用户设置中,然后重新启动应用程序。

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。

更新

Vlad 让我检查一下 CurrentThread 的 CurrentUICulture 是什么。所以我在我的构造函数上添加了一个 MessageBox 来告诉我 CurrentUICulture 两字母代码是什么以及我的 Language 用户字符串的值。

MessageBox.Show(string.Format("Current Language: {0}\nCurrent UI Culture: {1}", Properties.Settings.Default.Language, Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName));

加载错误的语言时,Language 字符串和 CurrentUICulture 都有错误的语言。所以我猜 CurrentUICulture 已被清除,我的问题实际上与语言设置有关。

所以我想问题是我的应用程序有时会加载以前保存的语言字符串,而不是最后保存的语言字符串。如果应用程序重新启动,它将加载实际保存的语言字符串。

4

5 回答 5

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(). 如果您关闭应用程序并再次打开它,您的(新)设置将被采用。

所以我们必须想办法重新初始化表单以使新的语言设置发生。

于 2010-08-20T12:00:32.647 回答
2

你能检查一下你的线程是CurrentUICulture什么吗?

我记得有像你这样的问题;它是通过重新加载包含要本地化的字符串的资源字典来解决的:

Thread.CurrentThread.CurrentUICulture = <new culture>;
ResourceDictionary newDict = new ResourceDictionary();
newDict.Source = localizedStrings.Source;
localizedStrings = newDict;

(而且这种方法也可以动态工作;这里有更多信息)。

于 2010-04-28T08:23:05.087 回答
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;

希望有帮助!

于 2012-10-24T22:57:37.920 回答
0

您可以通过关闭打开的表单并重新创建它们来简单地“重置”您的应用程序。然后您可以在用户更改设置时直接设置文化。

此外,尝试提供一些调试输出,以便您了解设置的值以及文化是否真的是您所期望的。

编辑:我的猜测:由于必须将数据写入文件,然后从该文件加载,因此您可能重启得太快而无法完成写入。

于 2010-04-28T08:40:49.120 回答
0

通过使用 CurrentThread.CurrentUICulture,然后更改表单,您无需重新启动应用程序。在这里参考我的旧帖子

于 2010-10-27T04:36:41.187 回答