设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

构建多语言的WPF应用

2014-7-9 10:25| 发布者: joejoe0332| 查看: 5975| 评论: 0|原作者: 徐继开, TimBao, chasehong, 无若, 0x0bject, 请叫我益达张, 卖茄子, 地狱星星|来自: oschina

摘要: 在WPF应用程序中搭建多语言支持(Multilingual Support)是我最近在做的一件事,对于不使用英语的人士而言,此举提高了程序的可用性。实现起来要完成以下目标:…… ...


Rinse and Repeat - 字体大小与流方向

某些语言的字符集包含十分复杂的图形元素,以致在拉丁文可以辨认的字符大小,用来显示这些语言的时候,变得模糊不清了。你注意到CommonViewModel提供了HeadingFontSize和MinFontSize属性。这就为本地化标题和剩余的本地化文本相应地提供了字体大小。例如日文的字体大小就大于英文。

幸运的是,使用类似下面的这个模式就可以把上述的文字尺寸绑定到共享的样式中,而不需要值转换器:

1<Style TargetType="{x:Type TextBlock}">
2    <Setter Property="FontSize" Value="{Binding Path=MinFontSize,
3            Source={x:Static vm:CommonViewModel.Current}}" />
4    <!-- Remaining setters ... -->
5</Style>

下图显示的是两个同样界面不同语言下的差异:


也有一些语言是从右向左读的,例如阿拉伯语和希伯来语。为了让UI正确的定位到这些语言,反转接口是有意义的,否则会带来一些混淆,如果在使用程序的时候读取的顺序和逻辑的顺序不一致。

幸运的是,WPF有一个方便的属性可以完成反转整个UI的艰苦工作:

FrameworkElement.FlowDirection

是什么让这个功能相当强大,我只需要绑定一个包含在主窗口内的根级别控件,因为这个值是由它下面的每个FrameworkElement的在视觉层次继承。绑定仅仅需要查看CommonViewModelIsRightToLeft属性,转换到(通过其他的值转换器)FlowDirection的枚举值。自定义的标记扩展被创建,遵循以前类似的模板,简化为XAML:

1<Window x:Class="RePaver.UI.MainWindow" ... >
2    <DockPanel FlowDirection="{ext:LocalisedFlowDirection}">
3        <!-- Contents -->
4    </DockPanel>
5</Window>

鉴于到上述功能的强大,这里仍然要考虑一些陷阱和要点:

  • 自定义面板自动反转布局,所以你不需要创建一个IsRevered属性(或者类似的)或者按照你的估算调整ArrangeOverride。

  • 位图和形状(如线路)是反转的。如果您想要保留这些,呈现独立的流向(如公司的logo或者商标),那么你需要重写FlowDirection,设置它为LeftToRight。

  • 如果接口有RightToLeft的FlowDirection,而元素(如Image)具有LeftToRight的FlowDirection,那么元素的Margin会以RightToLeft的方式展示。由于Padding展示在元素内部可视层次,所以一个padding将会以LeftToRight的方式展示。

  • TextBoxes包含语言恒定的数据,应当将FlowDirection设置为LeftToRight。理想情况下,此属性应设置为尽量减少重复并保证一致性的风格。

所以,下面就是赶时髦的“处理后”的截图:

注意路径,旋转选择控件,输入输出文本框是以从左至右的方式展示,这与语言无关。这是因为这些元素是特定的问题区域,如果它们以从右至左的方式展示,就没有道理了(可能会引起误解)。


总结

现在明白了——一个局部的WPF应用程序可以在运行时动态地改变UI。第一次运行它是在法语的本地计算机环境中,瞧, il est affich&eacute; en Fran&ccedil;ais. 它们都来自同一种语言版本。

最后一个要点需要注意,这里不做详细介绍,整个UI布局以流体方式布局,这样的布局会自动调整以适应内容。 而不是显式地设置宽度和高度, 网格的行/列定义,等等。这些都是“自动”为左的,同时还可以定义最小和最大值。这是很普通的实例中极佳的一个(而不是特定的本地化), 但当切换语言的时候,不允许这样的实例真的显示出来。

后记

软件开发中本地化是一个热门的话题,理所当然,我也不是唯一一个写这方面的人。事实上,我也发现了一些人在做同样的事:

  • Sebastian Przybylski (article) 也把UI文本存储在XML文件作为嵌入资源,而把XAML直接绑定到XML资源上而不是通过ViewModel.

  • David Sleeckx (article) 使用自定义标记拓展来检索本地缓存的翻译文本,或者调用Google语言API来实现实时翻译。

  • 'SeriousM' 在CodePlex上更新了 WPF本地化拓展 . 它是通过提取资源文件/资源程序集中的本地化文本(或其他值)来实现的。

显然,实现WPF程序的本地化有很多种选择,它们并不互斥。根据你的权衡,我所提到的实现方法仅适用于你程序的部分,另一部分则会出现在其他的地方。所以你要根据你的需求,随意调整实现方法。




酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部