每种语言的

时间:2016-02-23 21:12:50

标签: c# localization globalization resource-files

我创建了一个新的C#类库项目,它将包含所有翻译的资源文件。我见过的例子有一个扁平结构,每种语言有一个巨大的资源文件,如下所示:

  • Messages.resx
  • Messages.fr-FR.resx

但对于此特定项目,最好将资源文件拆分为逻辑分组:

  • SystemMessages.resx
  • UserMessages.resx
  • SystemMessages.fr-FR.resx
  • UserMessages.fr-FR.resx

当我们添加更多资源文件和更多翻译时,这将变得混乱,因此为每种语言设置子文件夹会更容易管理,例如。

  • 烯GB \ SystemMessages.resx
  • 烯GB \ UserMessages.resx
  • FR-FR \ SystemMessages.fr-FR.resx
  • FR-FR \ UserMessages.fr-FR.resx

但这样做会将语言代码添加到命名空间,例如Translations.en-GB.SystemMessages.MyString我假设因为en-GB现在位于名称空间中,资源管理器将无法再找到fr-FR翻译。

如何根据语言代码将资源放入子文件夹?

1 个答案:

答案 0 :(得分:1)

让我们假设您的项目如下:

enter image description here

您可以根据线程文化使用不同的ResourceManager 使用小T4模板,您可以强类型化(迭代资源文件并为每个字符串创建属性)

using ConsoleApplication6.Translations.French;
using System;
using System.Resources;

namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(SystemMessagesManager.GetString("Title"));
            Console.ReadLine();
        }

       public static class SystemMessagesManager
       {
           static ResourceManager rsManager;
           static SystemMessagesManager()
           {
               //Get the current manager based on the current Culture
              if (Thread.CurrentThread.CurrentCulture.Name == "fr-FR")
                   rsManager = SystemMessagesFrench.ResourceManager;
              else if (Thread.CurrentThread.CurrentCulture.Name == "el-GR")
                   rsManager = SystemMessagesGreek.ResourceManager;
              else
                   rsManager = SystemMessagesEnglish.ResourceManager;
           }
           public static string GetString(string Key)
           {
              return rsManager.GetString(Key) ?? SystemMessagesEnglish.ResourceManager.GetString(Key);
           }
       }
   }
}

关于T4模板,请检查:
How to use a resx resource file in a T4 template
您可以在下面看到示例代码 假设你在项目中有这个: enter image description here

使用以下模板,您可以自动生成课程:

<#@ template debug="false" hostspecific="true" language="C#" #>

<#@ assembly name="System" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Xml" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Linq" #>

<#@ output extension=".cs" #>
using System.Resources;
using System.Threading;

namespace YourNameSpace
{
    public static class SystemMessagesManager
    {       
        static ResourceManager rsManager;
        static SystemMessagesManager()
        {
               //Get the current manager based on the current Culture
              if (Thread.CurrentThread.CurrentCulture.Name == "fr-FR")
                    rsManager = SystemMessagesFrench.ResourceManager;
              else if (Thread.CurrentThread.CurrentCulture.Name == "el-GR")
                    rsManager = SystemMessagesGreek.ResourceManager;
              else
                    rsManager = SystemMessagesEnglish.ResourceManager;
         }
        private static string GetString(string Key)
        {
              return rsManager.GetString(Key) ?? SystemMessagesEnglish.ResourceManager.GetString(Key);
        }

        <# 
         XmlDocument xml = new XmlDocument();        
         xml.Load(Host.ResolvePath(@"ResourceStrings.resx"));

         foreach(string key in xml.SelectNodes("root/data").Cast<XmlNode>().Select(xn => xn.Attributes["name"].Value)){
         #>
public static string <#= key #> { get { return GetString("<#=key#>"); } }
        <# } #>                 
    }
}