我周末一直在做一个宠物项目,以了解有关 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.
发布评论
评论(5)
我遇到了同样的问题。我发现 Application.Restart() 并没有真正进行绝对重新启动,请参阅 MSDN。
因此 Application.Restart() 不会调用表单构造函数中的初始化内容
与 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
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.
您能否检查一下您的线程的
CurrentUICulture
是什么?我记得有一个像你这样的问题;通过重新加载包含要本地化的字符串的资源字典来解决这个问题:(
并且这种方法也可以动态工作;这里是一些更多信息)。
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:
(and this approach worked dynamically as well; here is some more information).
您可以手动更改当前表单的语言,类似于:
希望有帮助!
You could manually change the language of the current form similar to this:
Hope that helps!
您可以通过关闭打开的表单并重新创建它们来简单地“重置”您的应用程序。然后,当用户更改设置时,您可以直接设置区域性。
另外,尝试提供一些调试输出,以便您了解正在设置哪些值以及文化是否确实是您所期望的。
编辑:我的猜测:由于数据必须写入文件,然后从该文件加载,因此您可能重新启动得太快而无法完成写入。
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.
通过使用CurrentThread.CurrentUICulture,然后更改表单,您不需要重新启动应用程序。参考我的旧帖子这里
By using CurrentThread.CurrentUICulture, and then changing the form, you don't need to restart the application. Ref my old post here