Thread.CurrentThread.CurrentUICulture 无法一致工作

发布于 2024-08-30 12:49:11 字数 1488 浏览 11 评论 0 原文

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

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

Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
Application.Restart();

当应用程序启动时,Form 构造函数中的第一行代码(甚至在 InitializeComponent() 之前)会从设置中获取 Language 字符串并设置 CurrentUICulture,如下所示:

public Form1()
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
    InitializeComponent();
}

问题是,这并不能始终如一地工作。有时,一切正常,应用程序根据设置文件中保存的字符串加载正确的语言。其他时候则不然,并且应用程序重新启动后语言保持不变。

起初我以为我在重新启动应用程序之前没有保存语言,但事实并非如此。当正确的语言无法加载时,如果我关闭应用程序并再次运行它,正确的语言就会正确显示。因此,这意味着语言字符串已保存,但我的表单构造函数中的 CurrentUICulture 赋值有时不起作用。

有什么帮助吗?我是否遗漏了 C# 中线程的工作原理?这可能是特定于机器的,所以如果有什么区别的话,我使用奔腾双核 CPU。

更新

Vlad 让我检查 CurrentThread 的 CurrentUICulture 是什么。因此,我在构造函数中添加了一个 MessageBox,告诉我 CurrentUICulture 两个字母的代码是什么以及我的语言用户字符串的值。

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

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

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

I've been working on a pet project on the weekends to learn more about C# and have encountered an odd problem when working with localization. To be more specific, the problem I have is with System.Threading.Thread.CurrentThread.CurrentUICulture.

I've set up my app so that the user can quickly change the language of the app by clicking a menu item. The menu item in turn, saves the two-letter code for the language (e.g. "en", "fr", etc.) in a user setting called 'Language' and then restarts the application.

Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
Application.Restart();

When the application is started up, the first line of code in the Form's constructor (even before InitializeComponent()) fetches the Language string from the settings and sets the CurrentUICulture like so:

public Form1()
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
    InitializeComponent();
}

The thing is, this doesn't work consistently. Sometimes, all works well and the application loads the correct language based on the string saved in the settings file. Other times, it doesn't, and the language remains the same after the application is restarted.

At first I thought that I didn't save the language before restarting the application but that is definitely not the case. When the correct language fails to load, if I were to close the application and run it again, the correct language would come up correctly. So this implies that the Language string has been saved but the CurrentUICulture assignment in my form constructor is having no effect sometimes.

Any help? Is there something I'm missing of how threading works in C#? This could be machine-specific, so if it makes any difference I'm using Pentium Dual-Core CPU.

UPDATE

Vlad asked me to check what the CurrentThread's CurrentUICulture is. So I added a MessageBox on my constructor to tell me what the CurrentUICulture two-letter code is as well as the value of my Language user string.

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

When the wrong language is loaded, both the Language string and CurrentUICulture have the wrong language. So I guess the CurrentUICulture has been cleared and my problem is actually with the Language Setting.

So I guess the problem is that my application sometimes loads the previously saved language string rather than the last saved language string. If the app is restarted, it will then load the actual saved language string.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

香草可樂 2024-09-06 12:49:11

我遇到了同样的问题。我发现 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()。如果您关闭应用程序并再次打开它,您的(新)设置将被采用。

所以我们必须找到一种方法来再次初始化表单,以使新的语言设置发生。

I got the same problem. I figured out that Application.Restart() do not really make an absolutely restart, see MSDN.

So Application.Restart() do not call the initializing things within the forms constructor
like InitializeComponent(), more the "Applications are restarted in the context in which they were initially run."

So your code is correct

Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();

public Form1()
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
    //...
    InitializeComponent();
}

but it doesn't work this way with Application.Restart(). If You close the app and open it again your (new) settings are taken.

So we have to find a way to initialize the form again to make the new language settings happen.

关于从前 2024-09-06 12:49:11

您能否检查一下您的线程的 CurrentUICulture 是什么?

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

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

并且这种方法也可以动态工作;这里是一些更多信息)。

Could you check what is your thread's CurrentUICulture?

I remember having a problem like yours; it was solved by reloading the resource dictionary containing the strings to be localized:

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

(and this approach worked dynamically as well; here is some more information).

笔芯 2024-09-06 12:49:11

您可以手动更改当前表单的语言,类似于:

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;

希望有帮助!

You could manually change the language of the current form similar to this:

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;

Hope that helps!

仲春光 2024-09-06 12:49:11

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

另外,尝试提供一些调试输出,以便您了解正在设置哪些值以及文化是否确实是您所期望的。

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

You could simply "reset" your application by closing the open forms and re-creating them. Then you could directly set the culture when the user changes the setting.

Also, try giving some debug output so you see what values are being set and if the culture is actually what you expect.

EDIT: My guess: Since the data has to be written to a file, and then loaded from that file, you may be restarting too quickly for the write to have been completed.

凉宸 2024-09-06 12:49:11

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

By using CurrentThread.CurrentUICulture, and then changing the form, you don't need to restart the application. Ref my old post here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文