消息的动态本地化

时间:2014-07-17 08:07:07

标签: c# wpf winforms

我做了一个简单的消息本地化。所有消息都存储在静态类Lng

public static partial class Lng
{
    public static readonly string AppName = "My application";
    public static class Category1
    {
        public static readonly string ConfirmDelete = "Are you sure want to delete?";
    }
}

在代码中使用就像引用字段一样简单

MessageBox.Show(Lng.Category1.ConfirmDelete, ...

然后有一位经理,其中有以下内容:

  • 语言选择
  • 加载相应的翻译
  • 通过反思更新字段
  • 在应用程序出口处导出当前选定的语言以进行更新(如果选择了默认语言 - 为任何其他语言创建第一个翻译)

这与语言文件的外观无关,但这里有一个反射部分

TranslateLng("Lng.", typeof(Lng));
...

private static void TranslateLng(string parent, Type type)
{
    foreach (Type nested in type.GetNestedTypes())
    {
        string child = string.Format("{0}{1}.", parent, nested.Name);
        TranslateLng(child, nested);
        foreach (var field in nested.GetFields())
        {
            string key = child + field.Name;
            DefaultAdd(key, (string)field.GetValue(null)); // store value in default language dictionary (if not created yet)
            field.SetValue(null, GetValue(key)); // get value for currently selected language
        }
    }

这个系统有一个问题:所有消息都在一个类中定义,这需要手动管理(更新使用它们的代码时删除和更新消息)。

我正在考虑更改管理器以动态注册字符串并将使用简化为

MessageBox.Show(Lng.Text("Are you sure want to delete?"), ...

因此,文本定义在它使用的位置,重复的文本可以由经理处理等等。

但有两个问题:

  • 我需要在应用程序运行结束时提供所有消息的完整列表,以导出完整的消息列表(对于当前选择的语言)。如果某些Lng.Text()从未被调用过怎么办?有没有办法注册,因为它们在代码中使用(编译时?)?因此,即使从不使用代码的和平,所有呼叫都将以某种方式注册。

  • 如何生成key。我可以使用CallerMemberName,但是右键更有用,因为它们正在说明确切的目的。例如,Lng.Configuration.Appearance.CaptionText。我可以打电话给Lng.Text(key, message),但后来我必须管理钥匙,确保其独特性,这对我没有吸引力。

1 个答案:

答案 0 :(得分:1)

我最近参与了一个国际化的项目,我们使用ResourcesSisulizer计划的联合取得了巨大的成功。在提取资源时手动输入密钥时,资源可以解决您的关键问题。你也得到Resharper的大力支持,这使整个过程变得轻而易举。

Sisulizer然后用于提取资源以及在Win Forms和WPF类中硬编码的字符串。它可以导出CSV,您可以为您的译员提供,它也支持pseudo translation,这使得测试此类应用程序也非常容易。