网上看了一些,还要自己编译生成.resources文件,然后动态加载,这个方法没有试,感觉也挺麻烦的,本来VS可以很方便地生成.resx的资源文件,然后一起编译时DLL,搞了很久也没有弄清楚如何将一个个字符串分别读出,不过也通过其它方法实现了多语言的支持,唯一一点遗憾就是需要重启程序,其实这个在很多情况下也是可以接受的嘛,至于立即生效的方法以后再研究吧。
首先,生成资源文件。
1.将FORM的属性Localizable置为true
2.将Form的属性Language置成default,用于通过操作系统的UI界面语言设置自动加载默认语言,如果设置的语言找不到的话则默认成中文(可能默认成英文好点),设置各个控件的属性,填写完整。
3.将Form的Language置成English(United States)即en-US或其它语言,修改各控件上的字符串,一旦改变某个控件的属性,VS就会自动生成一个资源文件formname.en-US.resx。
这样就可以分别编辑各种语言的资源文件,当你选择Language时VS会给你加载相应的语言界面,当然你也可以进行修改。本来想修改这个语言属性来显示不同语言界面,但Form类中没有这上属性,应该是VS在设计时添加的一个属性。
然后,在程序启动时进行语言设置的加载,核心代码为:
static void Main() { if (WordCracker.Config.ConfigManager.Language != "default") { System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(WordCracker.Config.ConfigManager.Language); } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); }
其中,WordCracker.Config.ConfigManager是我写的一个操作xml配置文件的一个类,代码如下:
namespace WordCracker.Config { static class ConfigManager { private static XmlDocument doc = new XmlDocument(); private static FileInfo file = new FileInfo("config.xml"); static ConfigManager() { if( !file.Exists ) return; FileStream fs = new FileStream(file.Name, FileMode.Open); doc.Load(fs); fs.Close(); } public static string Language { get { XmlNode lan = doc.SelectSingleNode("/configuration/UI/language"); if (lan == null) return "default"; else return lan.InnerText; } set { XmlNode lan = doc.SelectSingleNode("/configuration/UI/language"); if (lan == null) { // create node return; } lan.InnerText = value; if (file.Exists) file.Delete(); doc.Save(file.Name); } } } } 配置文件config.xml放在与程序同一目录中,内容为:当然,这里还可以添加其它配置信息,就是一个小软件,我也没有添加太多东西
<?xml version="1.0" encoding="utf-8" ?>
<configuration><br><ui><br><language>en-US</language><br></ui><br></configuration>
到这里就实现了启动时检测配置文件中设置的语言,并加载相应语言的界面,但是还没有修改语言的功能, 修改语言的操作写在一个菜单中,一个显示中文一个显示英文,代码如下:
private void menuOptionsLanguageChinese_Click(object sender, EventArgs e) { WordCracker.Config.ConfigManager.Language = "zh-cn"; PromptRestart(); } private void menuOptionsLanguageEnglish_Click(object sender, EventArgs e) { WordCracker.Config.ConfigManager.Language = "en-US"; PromptRestart(); } private bool PromptRestart() { if (MessageBox.Show("If you want to chang language, the program need restart, would you restart now?", "Restart needed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) { System.Windows.Forms.Application.Restart(); return true; } return false; }
这里另一个问题就出来了,这个弹出的提示要重启的消息是用中文还是用英文,最好也写到配置文件里,并检测语言设置,设置为什么语言就显示什么语言的提示消息。
这种方法的缺点就是不能立即生效,如果要立即生效的话需要重新手动加资源,需要手动添加很多东西如果有必要的话才那样干吧。