使用i18N最好的GTK ##与WPF相似的可能性有哪些?

时间:2012-09-11 06:12:25

标签: c# wpf internationalization gtk gtk#

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

文本文件的编写方式如下:
<命名空间>。<类名称>。<性> =翻译文本。
对于每个翻译的控件/ UI项,代码不得过多扩展 有什么可能性?

对于Windows和Linux,是否有一个很好的链接描述i18n和GTK#?

1 个答案:

答案 0 :(得分:0)

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

我们实施了一个非常有效的想法。

GTK#中的GUI定义位于XML文件gtk-gui/gui.stetic中(WPF具有XAML文件)。 我们的想法是通过XSLT生成其他代码文件。

额外生成的代码支持i18n和我们的Translator类。 如果文化发生变化,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=Ω
㗔㲀䃽䄈䄙䄜礽祉...祿福囍</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=㗔㲀䃽䄈䄙䄜礽祉...祿福囍</property>
            <!-- ... -->
          </widget>

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

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

  • 此类property节点的父节点始终为widget节点
  • 每个widget节点都包含其中的Widget的名称和类型 属性。
  • 此类widget节点的父节点始终是child节点 - 除外 它不是根节点的子节点。
  • 每个child节点的父节点也是父节点widget

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

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

  1. 获取所有类的列表,这些类派生自Gtk.BinGtk.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.Window / Gtk. ...)必须插入项目文件中 - 这个由额外的XSLT完成。

  7. 这很有效。

    优点:

    它的优点是可以自动提取翻译。 每个新设计的UI类派生自e。 G。每次构建时会自动处理Gtk.WindowGtk.Bin。 这种类型的i18n可以通过改编的XSL文件适应WPF。

    缺点:

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

    翻译

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

    图片

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

    环境

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