具有用C#编写的相同业务代码的应用程序应在Windows(WPF)和Linux(GTK#,Mono)下运行。
用户界面将通过WPF for Windows和GTK#for Linux单独完成
应用程序的用户语言在任何对话框的操作过程中都可以更改,并更新控件中的所有可翻译文本
翻译的文件可用于这两个部分。
WPF的i18n在自己的库中实现,并为当前文化提供单例,其属性包含文本。这些属性用于XAML中的绑定。
因此,存在一个PropertyChanged事件,我们希望在GTK#方面拥有什么。
我们希望在Windows上运行Monodevelop中的应用程序以进行调试。如果语言可更改/更改,则只打开一个对话框。
文本文件的编写方式如下:
<命名空间>。<类名称>。<性> =翻译文本。
对于每个翻译的控件/ UI项,代码不得过多扩展
有什么可能性?
对于Windows和Linux,是否有一个很好的链接描述i18n和GTK#?
答案 0 :(得分:0)
我们实施了一个非常有效的想法。
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文件:
Gtk.Bin
,Gtk.Window
(临时xml文件)生成XXXXXTranslation
类看起来像这样:
namespace NameSpaceXy
{
public class EntryWidgetTranslation: TranslationTemplate
{
[Translation(@"default title")]
public string TitleLabel_LabelProp { get; set; }
//..
为每个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);
//..
}
}
}
最后这两个生成的代码文件(每个类,派生自Gtk.Bin
/ Gtk.Window
/ Gtk.
...)必须插入项目文件中 - 这个由额外的XSLT完成。
这很有效。
它的优点是可以自动提取翻译。
每个新设计的UI类派生自e。 G。每次构建时会自动处理Gtk.Window
或Gtk.Bin
。
这种类型的i18n可以通过改编的XSL文件适应WPF。
必须在Gtk#中调用生成的方法Translate()
,在适当的情况下,
至少在显示元素的位置以及在更改语言/文化时,如果元素是可见的。 (由于其绑定功能,WPF / XAML不需要Translate
方法。)
Translator类是一个自己的公司内部实现,它为当前的集合文化提供正确的字符串 - 这里内部读取该文化的XML文件。 由于Unicode的优势和添加换行符/多行字符串,我们将语言文件更改为XML文件。 它现在是一个序列化的Dictionary实例。
我们还添加了文化依赖图片,可以使用此部分XPath表达式gui.stetic
从property[@name='Pixbuf'][../@class='Gtk.Image']
调用的XML文件中轻松提取。
我在Windows中运行MonoDevelop并在批处理脚本中使用MsXsl.exe
,可能它也会在Linux中与其他XSLT处理器一起运行。