关于让WPF软件界面支持全球化和本地化 關於讓WPF軟件界面支持全球化和本地化
周银辉有朋友询问如何让WPF应用能够提供多语言支持(中文,英文,日文.....),我的建议是:(1)抛弃WinForm时代的资源存储方式(2)利用WPF的动态资源特性. 周銀輝有朋友詢問如何讓WPF應用能夠提供多語言支持(中文,英文,日文.....),我的建議是:(1)拋棄WinForm時代的資源存儲方式(2)利用WPF的動態資源特性.
下面简单介绍一下并打造一个简单的DEMO: 下面簡單介紹一下並打造一個簡單的DEMO:

1,语言资源文件怎样存储 <br /> 我们知道以前(WPF以前)我们将界面上的各国语言分别存储在.resx类型的文件中,然后利用ResourceManager来得到相应资源并根据当地的CultureInfo来给界面文本赋值.这是可行的.但在WPF中存在的一个问题是:我们必须为每个控件在后台代码中来Code这些逻辑,因为XAML是找不到.resx类型中的资源的.但WPF中绝大多数界面元素都是在XAML中定义的这是一件很麻烦的事情.所以我们应该抛弃这样的做法. 1,語言資源文件怎樣存儲 <br />我們知道以前(WPF以前)我們將界面上的各國語言分別存儲在.resx類型的文件中,然後利用ResourceManager來得到相應資源並根據當地的CultureInfo來給界面文本賦值.這是可行的.但在WPF中存在的一個問題是:我們必須為每個控件在後台代碼中來Code這些邏輯,因為XAML是找不到.resx類型中的資源的.但WPF中絕大多數界面元素都是在XAML中定義的這是一件很麻煩的事情.所以我們應該拋棄這樣的做法.
WPF中的资源继承了以前的多种存储形式,但可以在XAML和C#(或其他)中通行的有两中,一个是Content,一个是Resource,前者是"内容",既是松散的资源链接,后者是被编译并嵌入的资源,注意,你在设置资源文件属性的时候会发现还有一个很让人混淆的Embedded Resource ,这也是内嵌的资源,但其被压缩为二进制形式,既和以前WinForm的内嵌资源相同,Resource和Embedded Resource在编码上的区别是前者可以通过Uri找到,这是XAML需要的方式,后者可以通过Stream找到,这可以通过编写c#代码来查找资源. WPF中的資源繼承了以前的多種存儲形式,但可以在XAML和C#(或其他)中通行的有兩中,一個是Content,一個是Resource,前者是"內容",既是鬆散的資源鏈接,後者是被編譯並嵌入的資源,注意,你在設置資源文件屬性的時候會發現還有一個很讓人混淆的Embedded Resource ,這也是內嵌的資源,但其被壓縮為二進制形式,既和以前WinForm的內嵌資源相同,Resource和Embedded Resource在編碼上的區別是前者可以通過Uri找到,這是XAML需要的方式,後者可以通過Stream找到,這可以通過編寫c#代碼來查找資源.
所以,在这里看来Content是我们保存语言资源的良好方式,由于其是松散的资源链接,所以为应用程序添加新的语言包时就可以不重新编译了,只需将对象的语言文件拷贝到指定的文件夹即可. 所以,在這裡看來Content是我們保存語言資源的良好方式,由於其是鬆散的資源鏈接,所以為應用程序添加新的語言包時就可以不重新編譯了,只需將對象的語言文件拷貝到指定的文件夾即可.

2,界面元素如何链接到语言文本 <br /> 这是StaticResource 和DynamicResource要做的事情,比如: 2,界面元素如何鏈接到語言文本 <br />這是StaticResource和DynamicResource要做的事情,比如:

< Button Content = " {DynamicResource OK} " /> < ButtonContent = " {DynamicResourceOK} " />
至于是使用StaticResource 还是DynamicResource,这取决于你是否要在运行时动态切换,如果仅仅是软件启动的时候才切换语言StaticResource就可以了.至於是使用StaticResource還是DynamicResource,這取決於你是否要在運行時動態切換,如果僅僅是軟件啟動的時候才切換語言StaticResource就可以了.

3,OK 实战一下: 3,OK實戰一下:
3.1 新建项目,并在项目中新建一个Lang文件夹用于保存我们的语言文件 3.1新建項目,並在項目中新建一個Lang文件夾用於保存我們的語言文件

3.2 在Lang文件夹中,新建"ResourceDictionary(WPF)",命名为" DefaultLanguage.xaml ",并将其BuildAction设置为Page,这是一个默认语言资源文件,其将被编译(而不是松散链接,这样可以确保在软件语言包丢失或没有某国家或地区的对应语言包时可以有一种默认的界面语言):我们这里采用英文作为默认语言: 3.2在Lang文件夾中,新建"ResourceDictionary(WPF)",命名為" DefaultLanguage.xaml ",並將其BuildAction設置為Page,這是一個默認語言資源文件,其將被編譯(而不是鬆散鏈接,這樣可以確保在軟件語言包丟失或沒有某國家或地區的對應語言包時可以有一種默認的界面語言):我們這裡採用英文作為默認語言:
< ResourceDictionary xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation " < ResourceDictionaryxmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml "
xmlns:sys = " clr-namespace:System;assembly=mscorlib " >

< sys:String x:Key = " OK " > < sys:Stringx:Key = " OK " >
OK
</ sys:String >

< sys:String x:Key = " Cancel " > < sys:Stringx:Key = " Cancel " >
Cancel
</ sys:String >

</ ResourceDictionary >
然后,我们添加另一国语言,比如中文,在Lang文件夹中,新建"ResourceDictionary(WPF)",命名为" zh-CN.xaml ",并将其BuildAction设置为Content,将CopyToOutputDirctory设置为"if new",这样,我们的中文语言文件为将被拷贝到应用程序目录下的Lang目录下,其他的非默认语言的语言文件都应该采取这种方式.然後,我們添加另一國語言,比如中文,在Lang文件夾中,新建"ResourceDictionary(WPF)",命名為" zh-CN.xaml ",並將其BuildAction設置為Content,將CopyToOutputDirctory設置為"if new",這樣,我們的中文語言文件為將被拷貝到應用程序目錄下的Lang目錄下,其他的非默認語言的語言文件都應該採取這種方式.
< ResourceDictionary xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation " < ResourceDictionaryxmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml "
xmlns:sys = " clr-namespace:System;assembly=mscorlib " >

< sys:String x:Key = " OK " > < sys:Stringx:Key = " OK " >
确定 確定
</ sys:String >

< sys:String x:Key = " Cancel " > < sys:Stringx:Key = " Cancel " >
取消 取消
</ sys:String >

</ ResourceDictionary >

3.3 为了让编码人员在设计器(比如VS,Blend)中所见即所得地看到界面文本,我们应该将默认语言资源加入到应用程序的资源列表中: 3.3為了讓編碼人員在設計器(比如VS,Blend)中所見即所得地看到界面文本,我們應該將默認語言資源加入到應用程序的資源列表中:
< Application x:Class = " LangDemo.App " < Applicationx:Class = " LangDemo.App "
xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml "
StartupUri = " Window1.xaml "
>

< Application.Resources >
< ResourceDictionary >
< ResourceDictionary.MergedDictionaries >
< ResourceDictionary Source = " lang\DefaultLanguage.xaml " /> < ResourceDictionarySource = " lang\DefaultLanguage.xaml " />
</ ResourceDictionary.MergedDictionaries >
</ ResourceDictionary >
</ Application.Resources >

</ Application >

这样我们就可以在设计器中使用这些资源了:這樣我們就可以在設計器中使用這些資源了:

我们可以看到由于我们加载的默认语言是英文,设计器中我们的窗口界面上显示的是对应的英文文本.我們可以看到由於我們加載的默認語言是英文,設計器中我們的窗口界面上顯示的是對應的英文文本.

3.4 软件启动时加载对应的本地化的语言: 3.4軟件啟動時加載對應的本地化的語言:

public partial class App : Application public partial class App:Application
{

protected   override   void OnStartup(StartupEventArgs e) void OnStartup(StartupEventArgse)
{
base .OnStartup(e);
LoadLanguage();
}

private   void LoadLanguage()
{
CultureInfo currentCultureInfo = CultureInfo.CurrentCulture; CultureInfocurrentCultureInfo = CultureInfo.CurrentCulture;

ResourceDictionary langRd = ResourceDictionarylangRd =   null ;

try
{
langRd =
Application.LoadComponent(
new Uri( @" Lang\ "   + currentCultureInfo.Name +   " .xaml " , UriKind.Relative)) " .xaml " ,UriKind.Relative))
as ResourceDictionary;
}
catch
{
}

if (langRd !=   null )
{
if ( this .Resources.MergedDictionaries.Count >   0 )
{
this .Resources.MergedDictionaries.Clear();
}
this .Resources.MergedDictionaries.Add(langRd);
}


}
}

当软件启动时,我们根据当地的CultureInfo来加载对应的语言文件(如果该语言文件存在的话),由于界面上的文本不是硬编码进去的,而是采用DynamicResource,当后台Resource改变时,前台的引用也会动态改变,OK,当软件启动后,我们的界面就自动的切换了,我这台电脑上是中文:當軟件啟動時,我們根據當地的CultureInfo來加載對應的語言文件(如果該語言文件存在的話),由於界面上的文本不是硬編碼進去的,而是採用DynamicResource,當後台Resource改變時,前台的引用也會動態改變,OK,當軟件啟動後,我們的界面就自動的切換了,我這台電腦上是中文:


當然,本地化還有很多內容,比如貨幣數字,閱讀順序等,這裡僅僅提供了一個思想,你還可以在這裡下載DEMO

狼翔月影 發表在 痞客邦 PIXNET 留言(0) 人氣()