2007年05月16日

 

开发国际化的软件要解决不同语言文化下的用户界面、字符串资源、日期货币显示格式等的本地化问题,除了日期货币等不同国度的显示格式外,都是关于维护一个资源集合的问题。集合中有针对不同语言文化的资源,包括用户界面的显示内容与方式,翻译好的字符串资源,声音资源,图片资源等。其实日期货币格式也是一个集合,只不过系统不是做为一个资源集合的方式来支持。

.NET为本地化工作提供了许多便利。例如Form有一个Bool属性Localizable,打开后可以为Form选择不同的Language属性,从而VisualStudio自动建立此Form在不同Language下的资源文件。当Form在设计期时,通过切换不同的Language属性就可以设计各个本地化版本。VisualStudio还可以识别不同Language下的规范命名,自动将各个Language版本的资源分别编译生成为一个个的Satlite Assembly,并生成在正确的资源搜索路径上,而且为Form生成的C#代码,可以在启动时根据线程环境选择正确的资源,并且在初始化界面元素时使用资源中的内容。基本代码如下:

System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main));//自动完成根据环境加载正确资源,支持Fallback

resources.ApplyResources(this.button1, "button1");//所有的界面元素都会使用资源进行初始化

resources.ApplyResources(this, "$this");

 

而没有打开LocalizableForm初始化代码如下:

this.Text = "Form1";

 

.NETSDK中还提供了WinRes.exe,实现在VisualStudio之外对Form的各个本地化版本进行翻译、修改。

 

以上的内容在微软文档及参考书中都可以找到,但是如何实现软件中的非Form元素资源的本地化呢?

第一个想到的办法,就是在某个FormRES资源文件中加入其它类型资源,如字符串资源等,但由于这些RES都是由VisualStudio自动生成的,在下次修改Form再次生成时,手工加入的内容不会被保存。

第二个是使用VisualStudio为每个项目自动生成的一个Resource文件,位置在项目文件夹下Properties文件夹内,文件名是Resources.resx。但这如果加入其它语言文化的文件呢?手工方式可以是使用资源编译器编译手工编辑好的资源文件,再使用ALAssemblyLink)将其链接成一个SateliteAssembly。有没有自动办法呢?

在解决方案管理器中无法向Properties文件夹添加文件,所以只能手工添加,方法是先将Resources.resx复制重命名为类似Resources.zh-CN.resx的本地化资源文件名,再手工修改项目文件,如果使用C#就是扩展名为csproj的文件,加入以下内容:

<EmbeddedResource Include="Properties\Resources.zh-CN.resx">

<SubType>Designer</SubType>

</EmbeddedResource>

重新打开项目后,在解决方案管理器中就可以看到新加入的资源文件了,而且可以打开编辑。分别在Resources.resxResources.zh-CN.resx中添加一个字符串资源,内容分别为英文和中文,运行程序后可以看到已经根据环境显示本地化字符串了。而且支持Fallback,即删除Resources.zh-CN.resx中的对应字符串后,程序会自动显示Resources.resx中的内容。

 

这样就可以在程序开发过程中,根据默认的资源开展本地化工作,将内容保存到对应的资源文件中,VisualStudio会自动将规范命名的资源文件生成对应的SateliteAssembly

 

VisualStudio还为Resources.resx自动配置成生成StronglyTyped类,这个类只要生成一次就行了,使用它访问资源会自动支持多个SateliteAssembly