Posted on 2006-03-04 19:48
Programmer 阅读(1931)
评论(3) 编辑 收藏 网摘 所属分类:
.Net
使用 .net 开发一个支持多语言的 WinForm 应用程序是很方便的。特别是在 .net framework 2.0 中,Visual Studio 2005 做了进一步的改进。它默认地为每个资源文件(.resx)添加一个叫 ResXFileCodeGenerator 的自定义工具来简化读取资源的操作。我们常用的一些软件,比如 BitComet、Skype 等都可以在菜单中设置界面显示的语言。那么如果要在我们的 .net 程序中实现这个功能该怎么办呢?
在 .net 程序中,多语言的支持是以 satellite assemblies 的形式实现的,只要在相应的位置存在某种语言的 satellite assembly 即可。而在 Visual Studio 中,只需要为每个资源文件添加相应语言的资源文件就可以了。比如:Resources.resx 对应的简体中文的资源文件叫 Resources.zh-CHS.resx,英语的叫 Resources.en.resx。至于如何生成合适的 satellite assembly,就交给 Visual Studio 来完成了。
在程序运行的时候,到底使用哪个资源文件,是由 Thread.CurrentThread.CurrentUICultrue 来决定的。我们暂且将需要用到资源文件的地方分为两类:一是需要用到的时候才从资源文件读取的资源,比如使用 MessageBox 弹出的对话框中的消息内容等;另一类是窗体各个控件上显示的文字,比如 Label 控件的 Text 属性等。要改变程序使用的界面语言,首先必须改变 CurrentUICultrue 属性的值。我们可以发现,在改变了 CurrentUICultrue 的值后,第一类是没有问题。但是第二类就没有任何变化,窗体上各个控件显示的文字仍然没有变化。下面我们主要讨论第二类,也就是如何改变窗体控件的显示。我们均以 Label 控件为例进行说明。
方法一:
Label 控件在被创建好以后再改变 CurrentUICultrue,由于并没有任何用于处理当前线程的界面语言被改变的事件,也就是说此 Label 控件没有任何机会知道当前程序的界面语言已经被更改,因此 Label 控件的显示也不会有任何影响。既然是因为 Label 控件不知道 CurrentUICulture 已经改变了,那我们就想办法在改变 CurrentUICulture 的时候通知 Label 控件。这也使我们很自然地想到了这种情况和 Observer 模式极为相似。
上面这个方法是通过改变 CultureManager 类的 CurrentUICulture 属性值来达到更改程序的界面语言的目的的。在这个属性的 setter 方法中,它通知所有已经注册的窗体控件改变界面显示元素。
使用这个方法来更改程序的界面显示语言,逻辑很清晰,非常容易让人理解。但有一个缺点,就是需要对现有程序做较大程度的改动。
稍后再介绍另外一个方法。如果大家有什么更好的方法,也请多多交流哦! :)