Silverlight4的本地化和全球化对于我们构建全球化应用来说提供一定的便利性,下来我们就来探讨如何实现其本地化和全球化。
我们启动VisualStudio2010,并构建一个Silverlight Application:
-
ApplicationName:Jeriffe.SL.LocalGlobleApp
-
勾选:Host the Silverlight Application
-
New Web project type我们选择ASP.NET Web Application Project
接着我们来构建Resource文件,这里我们创建Resources文件夹,并添加Resource.resx、Resource.en-US.resx及Resource.zh-CN.resx 3个资源文件(注意:这3格资源文件共用一个Resources.Designer.cs),截图如下:

我们打开Resource.resx并添加2对Name Value串:
Label_EName EmployeeName
Label_Header Header
并且设置AccessModifier为Public:

以同样的方式我们在Resource.zh-CH.resx添加如下:

我们添加一个资源包装类ResourceWraper,我们为什么要添加这样一个类呢,我解释下缘由:
我们的资源文件(这里是Resource.resx、Resource.en-US.resx及Resource.zh-CN.resx)在我们每次修改后都会设置其后台Resources.Designer.cs内部的构造器
访问性修饰符为:Internal,如下图:

对于我们一般的C#应用来说internal是程序集内部可访问的,这个不存在什么问题,可是Silverlignt不知道为什么就不行,必须在这修改为Public才可以正常访问我们
的Resource,那么我们就会在每次修改完资源文件后还要修改这里的修饰符,这给我们的编程带来的一定的麻烦,有时候我们忘记修改这里会导致异常,所有我们这里
引入了一个包装类ResourceWraper,在包装类内部封装我们的资源文件类为一个只读的属性,这样我们就没有如上所述的困惑及麻烦,我们只需通过访问包装类来调用资源文件即可。包装类的代码如下:
namespace Jeriffe.SL.LocalGlobleApp.Resources
{
public class ResourceWraper
{
private static Resource resource = new Resource();
public Resource Resource
{
get
{
return resource;
}
}
}
}
接着我们在MainPage.xaml中添加如下:
<UserControl x:Class="Jeriffe.SL.LocalGlobleApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:res="clr-namespace:Jeriffe.SL.LocalGlobleApp.Resources"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" Loaded="UserControl_Loaded">
<UserControl.Resources>
<res:ResourceWraper x:Name="GlobleResource"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock
Name="lblHeader"
Grid.Row="0"
Foreground="Red"
FontSize="20"
Text="Design-Time"/>
<TextBlock
Grid.Row="1"
Margin="10"
FontSize="16"
Text="{Binding Resource.Label_EName,Source={StaticResource GlobleResource}}"/>
<TextBlock/>
<StackPanel
Grid.Row="2"
Orientation="Horizontal" >
<Button
Content="en-US"
Margin="5"
Name="btnen_US"
Click="btnen_US_Click"/>
<Button
Content="zh-CH"
Margin="5"
Name="btnzh_CN"
Click="btnzh_CN_Click"/>
</StackPanel>
</Grid>
</UserControl>
如上所示,加粗的字体有2部分:
- 第一部分资源声明,这里我们直接声明的是我们的资源包装类
- 第二部分是我们通过包装类来调用我们的资源文件写法。
接着就是我们的MainPage.xaml.cs文件的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Jeriffe.SL.LocalGlobleApp.Resources;
using System.IO.IsolatedStorage;
namespace Jeriffe.SL.LocalGlobleApp
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
lblHeader.Text = Resource.Label_Header;
}
private void btnen_US_Click(object sender, RoutedEventArgs e)
{
StorageLanguage("en-US");
}
private void btnzh_CN_Click(object sender, RoutedEventArgs e)
{
StorageLanguage("zh-CN");
}
private void StorageLanguage(string language)
{
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
if (settings.Contains(ConstDef.Language))
{
settings[ConstDef.Language] = language;
}
else
{
settings.Add(ConstDef.Language, language);
}
}
}
}
代码功能如下:
我们在页面Loaded事件中实现了资源文件的运行时加载
我们UI有2格Button,他们Click事件来实现Language的转变
我们把设置的Language存储到隔离存储中:IsolatedStorageSettings
最后我们在App.xaml.cs中添加如下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Globalization;
using System.Threading;
using System.IO.IsolatedStorage;
namespace Jeriffe.SL.LocalGlobleApp
{
public partial class App : Application
{
......
private void Application_Startup(object sender, StartupEventArgs e)
{
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
string language = "en-US";
if (settings.Contains(ConstDef.Language))
{
language = settings[ConstDef.Language].ToString();
}
CultureInfo culture = new CultureInfo(language);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
this.RootVisual = new MainPage();
}
......
}
}//辅助类
namespace Jeriffe.SL.LocalGlobleApp
{
public class ConstDef
{
public static string Language
{
get { return "language"; }
}
}
}
至此我们的应用已经构建完毕,但是我们还遗漏了最后也是最重要的一点,默认情况下Silverlight不会打包我们的语言资源文件到
XAP包中,我们必须需改Jeriffe.SL.LocalGlobleApp.csproj来使其自动的打包语言文件到XAP包:
这里我们用UE或者记事本打开Jeriffe.SL.LocalGlobleApp.csproj找到节点:并修改如下:
<SupportedCultures>zh-CN;en-US</SupportedCultures>
截图如下:

编译我们的应用,在HostWebProject的ClientBin目录下打开Jeriffe.SL.LocalGlobleApp.XAP包(修改扩展名XAP为zip打开,其实这就是格zip包,只是MS以XAP命名而已)
我们会看到如下:

好了,我们应用现在已经OK,运行Host Web Project我们的应用如下所示:

Click zh-CH按钮并刷新UI:

至此我们的应用就构建完毕了。