WPF & Sivlerlight 多语言解决方案本地化

多语言实现有很多方式, 最近一个WPF项目需要用到多国语言, 而其中以en-US为基本语言, 这样经过摸索终于找出一种解决方式.

1. WPF使用传统.net Resources.resx是可行的, 但总是觉得没有使用到WPF Resource 那么方便;

2.WPF resource 文件, 开始总是没法实现多语言方案,后来 在微软社区终于找到了对应用程序进行本地化 的这篇文章, 解决了我的问题.

3.下面描述一下我的步骤:

第一步:项目根目录下,新建资源文件Language.xaml, 如下:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation%22
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml%22
    xmlns:system="clr-namespace:System;assembly=mscorlib">
    <system:String x:Uid="MainOpen" x:Key="MainOpen">Open</system:String>
    <system:String x:Uid="MainNew" x:Key="MainNew">New</system:String>
    <system:String x:Uid="MainProperty" x:Key="MainProperty">Pproperty</system:String>
    <system:String x:Uid="MainSave" x:Key="MainSave">Save</system:String>
    <system:String x:Uid="MainPageNew" x:Key="MainPageNew">New Page</system:String>
    <system:String x:Uid="MainPageProperty" x:Key="MainPageProperty">Page Property</system:String>
    <system:String x:Uid="MainPageDel" x:Key="MainPageDel">删除页面</system:String>
</ResourceDictionary>

第二步:在App.xaml 中, 注意Source="/Language.xaml" 前面”/”,我开始这个地方搞了好长时间:

<Application.Resources>

    <ResourceDictionary >
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Language.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

这样可以在应用程序中任何地方都可以使用这个资源了, 至于怎么在WPF和silverlight中使用资源文件, 不在此文范围内, 请大家参考wpf资源的教程.

测试使用字符串资源, 新建一个窗口WinTest.xmal

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation%22
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml%22
    x:Class="Exio.NR.WPF.Designer.WinTest"
    x:Name="Window"
    Title="WinTest"
    Width="640" Height="480">

        <StackPanel VirtualizingStackPanel.VirtualizationMode="Recycling" HorizontalAlignment="Left" VerticalAlignment="Top">
        <Label Content="{DynamicResource MainNew}"/>
        <Label Content="{DynamicResource MainOpen}"/>
        <Label Content="{DynamicResource MainPageDel}"/>
        <Label Content="{DynamicResource MainPageProperty}"/>
        <Label Content="{DynamicResource MainSave}"/>
        </StackPanel>
</Window>

第三步: 使用MSBuilder编译

文本打开项目文件 xxx.csproj, 在每个PropertyGroup下添加<UICulture>en-US</UICulture>, 这一步是网上抄袭来的, 在后面会有问题报错, 暂时我们不管.

运行 MSBuilder编译, 具体命令为什么是3行,请参考 对应用程序进行本地化 的这篇文章:

msbuild /t:updateuid projName.csproj
msbuild /t:checkuid projName.csproj
msbuild projName.csproj

第四步: 错误解决

ok,我们做完了编译工作, 可以运行了, 启动程序, 会报一系列找不到App.xaml的错误, 最终发现是找不到对应语言的资源文件, 因为我的系统是中文系统, 也就是我编译的资源是 en-US的, 但是我的系统需要的 zh-CN, 怎么办哪?

2种方案:

  1).改项目文件 xxx.csproj, 在每个PropertyGroup下使用<UICulture>zh-CN</UICulture>, 再用MSBuilder编译, 运行没问题了;

  2).可是我的所有资源都是英文的,改过来工程浩大, 使用第一种方案,又感觉另类; 还有一种方式, 在我们AssemblyInfo.cs文件中添加一行[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] , 这个是设置最终回退的资源, 则当系统是中文的时候,先去找zh-CN下的资源,如果 zh-CN\projName.resources.dll不可用的时候例如这个dll被删除了),则中文版 Windows 将使用 en-US\projName.resources.dll。 ok, 再用MSBuilder编译, 运行没问题了;

这样我们编译生成了en-US版本的资源文件.

第四步: 使用LocBaml 导出(Parse) 资源和 生成(Trans) 新语言资源

具体参考对应用程序进行本地化 , 但是我的项目里面,我主要用到的是字符串资源, 通过LocBaml 导出的东东太多, 一个难找, 第二主要还是容易修改出错, 怎么办哪?

我修改了LocaBaml, TranslationDictionariesWriter.Write 中 65行(write out each resource 的foreach), 我只导出字符串资源文件.

foreach (DictionaryEntry entry in dict)
{
    BamlLocalizableResourceKey key = (BamlLocalizableResourceKey)entry.Key;
    BamlLocalizableResource resource = (BamlLocalizableResource)entry.Value;
    if (!key.ClassName.Equals("System.String")) continue;
    // column 1: baml stream name
    writer.WriteColumn(bamlStreamList[i].Name);

    // column 2: localizable resource key
    writer.WriteColumn(LocBamlConst.ResourceKeyToString(key));

    ……

注:这样做, 只适合我的解决方案, 因为我没有用到其它资源文件, 具体情况具体考虑,这个只是参考.

ok, 使用 LocBaml.exe /generate en-US/projName.resources.dll /trans:projName-cn.csv /out:E:\ /cul:zh-CN

拷贝到你的运行目录的zh-CN文件夹下试试看.

这种方式不好之处是无法切换语言, 但是他会根据你的操作系统来决定你的语言,让你不需要选择语言, 后面一篇文章将介绍怎么利用 WPF Resource来实现语言切换.

原文地址:https://www.cnblogs.com/yinpengxiang/p/1448409.html