0

使用 C# 编写的具有相同业务代码的应用程序应在 Windows (WPF) 和 Linux (GTK#, Mono) 下运行。
UI 将分别使用适用于 Windows 的 WPF 和适用于 Linux 的 GTK# 完成。
两种应用程序的用户语言在任何对话框中的操作期间都应可更改,并更新控件中的所有可翻译文本。
翻译后的文件应可用于这两个部分。WPF 的 i18n 在自己的库中实现,并为当前文化提供单例,其属性包含文本。这些属性用于 XAML 中的绑定。因此存在一个 PropertyChanged 事件,我们也希望在 GTK# 方面也有这个事件。我们还想在 Windows 上的 Monodevelop 中运行该应用程序以进行调试。如果语言可以更改/更改,则只打开一个对话框。

文本文件的编写方式如下:
<Namespace>.<Classname>.<Property> = 翻译文本。
对于每个翻译的控件/UI 项,代码不应扩展太多。
有哪些可能性?

是否有一个很好的链接来描述 i18n 与 GTK# for Windows 和 Linux?

4

1 回答 1

0

XSLT 从 UI 定义文件 gui.stetic 生成代码(XAML 的选项)

我们实现了一个想法,效果很好。

GTK# 中的 GUI 定义在 XML 文件中gtk-gui/gui.stetic(WPF 有 XAML 文件)。这个想法是通过 XSLT 生成额外的代码文件。

额外生成的代码通过我们的 Translator 类支持 i18n。来自 Translator 的派生类提供属性,如果文化发生变化,这些属性会改变其值。

XML 文件中的每个可以翻译的文本gtk-gui/gui.stetic都很容易提取:

<?xml version="1.0" encoding="utf-8"?>
<stetic-interface>
  <!-- ... -->
  <widget class="Gtk.Bin" id="NameSpaceXy.MenuWidget" design-size="800 480">
    <!-- ... -->
    <child>
      <widget class="Gtk.VBox" id="MainVBox">
        <!-- ... -->
        <child>
          <widget class="Gtk.Button" id="CJKButton">
                <!-- ... -->
                <property name="Label" translatable="yes" context="yes" comments="commented">context hint|happiness=Ω
㗔㲀䃽䄈䄙䄜礽祉...祿福囍&lt;/property>
                <!-- ... -->
          </widget>
          <!-- ... -->
        </child>
        <!-- ... -->
      </widget>
    <!-- ... -->
 </widget>
 <widget class="Gtk.Button" id="ExitButton">
    <!-- ... -->
    <property name="Label" translatable="yes">Exit</property>
    <!-- ... -->
  </widget>
    <!-- ... -->
          <widget class="Gtk.Button" id="CJKButton">
            <!-- ... -->
            <property name="Label" translatable="yes" context="yes" comments="comment for translator">context hint for translator|happiness=㗔㲀䃽䄈䄙䄜礽祉...祿福囍&lt;/property>
            <!-- ... -->
          </widget>

    <!-- ... -->
      <widget class="Gtk.Image" id="KeyboardImage">
        <!-- ... -->
        <property name="Pixbuf">file:en-us-640x232.png</property>
        <!-- ... -->
      </widget>
    <!-- ... -->
</stetic-interface>

在 GUI 设计器中,所有可以翻译的属性都将在 XML 文件中显示为一个 XML 节点,其名称property具有一个名为translatablevalue的属性yes。节点的内容是可以翻译的字符串。此外,每个这样的元素都可以用注释和翻译者的上下文提示来装饰——这两个字段可以在 UI 设计器中通过属性窗口进行编辑。(奇怪的是上下文提示以节点内容为前缀,由管道字符分隔。)

  • 这样一个节点的父property节点总是一个widget节点
  • 每个widget节点的属性中都包含 Widget 的名称和类型。
  • 这种节点的父widget节点始终是一个child节点——除非它不是根节点的子节点。
  • 每个child节点的父节点又是父widget节点。

因此,这个非常简单和智能的结构可以让我们找出哪个 Widget 实例的哪些属性是可翻译的,以及在哪里可以找到它的详细信息。

有了这些信息,我构建了预构建脚本和 XSL 文件:

  1. 获取所有类的列表,这些类派生自Gtk.Bin, Gtk.Window(临时 xml 文件)

  2. 从该列表创建一个批处理脚本文件

  3. 执行创建的批处理脚本文件,该文件为列表中的每个类执行:

  4. 生成的XXXXXTranslation类看起来像这样:

    namespace NameSpaceXy
    {
    
      public class EntryWidgetTranslation: TranslationTemplate
      {
        [Translation(@"default title")]
        public string TitleLabel_LabelProp { get; set; }
    //..
    
  5. 为每个 Gtk Widget 类生成部分类,它包含一个方法,如下所示:

     namespace NameSpaceXy
     {
       public partial class EntryWidget: ITranslateMethod
       {
         public void Translate()
         {
           GtkUtility.SetLabel(TitleLabel, Translator.Translation<EntryWidgetTranslation>().TitleLabel_LabelProp);
           GtkUtility.SetImage(KeyboardImage, Translator.Translation<EntryWidgetTranslation>().KeyboardImage_Pixbuf);
           //..
       }
      }
    }
    
  6. 最后,这两个生成的代码文件(每个类,派生自Gtk.Bin// ... Gtk.WindowGtk.必须插入到项目文件中——这是通过附加的 XSLT 完成的。

这行得通。

优点:

它的优点是可以自动提取翻译。每个新设计的 UI 类派生自 egGtk.WindowGtk.Bin在每次构建时自动处理。这种类型的 i18n 可以适应带有适应 XSL 文件的 WPF。

坏处:

生成的方法Translate()必须在适当的情况下在 Gtk# 中调用,至少在显示元素的位置和更改语言/文化时(如果元素可见)。Translate(由于其绑定功能,WPF/XAML 将不需要该方法)。

译者

Translator 类是一个自己的公司内部实现,它为当前设置的文化提供正确的字符串 - 这里在内部读取该文化的 XML 文件。由于 Unicode 和添加换行符/多行字符串的优势,我们将语言文件更改为 XML 文件。它现在是一个序列化的 Dictionary 实例。

图片

我们还添加了依赖于文化的图片,可以gui.stetic使用这个部分 XPath 表达式从调用的 XML 文件中轻松提取这些图片property[@name='Pixbuf'][../@class='Gtk.Image']

环境

我在 Windows 中运行 MonoDevelop 并MsXsl.exe在批处理脚本中使用,它可能也可以在 Linux 中与其他 XSLT 处理器一起运行。

于 2013-02-27T20:04:44.047 回答