使用约定对Silverlight应用进行国际化
2009-09-16 17:59
405 查看
关于对Silverlight进行国际化的方法,以前已经有过不少文章,我了解到的比较详尽的应当算是TerryLee的这一篇(http://kb.cnblogs.com/page/42913/)。正如这篇文章所指出的,Silverlight对国际化的支持存在不少小瑕疵,不过我最无法接受的问题是语法实在太过冗长:
<TextBlock Text="{Binding alabel, Source={StaticResource myStrings}}" />
如果界面上每个文本部分都要手工输入这么长串东西,迟早得把写代码的人搞疯掉。就算真的有毅力全部输入,这么一大坨的XAML对看代码的人无疑也是一种折磨。附带一提,有些文章提出的国际化方案似乎意犹未尽,在Binding后面还要再加上一个ConvertParameter,难道这些人对裹脚布有特殊的偏好?
我在项目中为了减少国际化的工作量,同时也为了让代码变得干净清爽一点,采用了另外一种基于约定的国际化方案。其实背后的道理说穿不值一文钱,就是让界面上所有待翻译的文字输入时遵循一定的格式,比如“rs:alabel”,程序使用VisualTreeHelper这个方便的类遍历界面上所有组件,找到所有符合规则的文字,然后翻译成对于当前语言的内容。这个方案简单而且工作得很好,因为我们的界面中需要国际化的部分90%以上不脱TextBlock、Button和DataGrid这三种组件,如果有特殊的控件不能用此方式进行国际化也没有关系,毕竟绝大部分工作都能够很简单的完成了。
换言之,现在添加控件的时候只要这样写:
<TextBlock Text="rs:alabel" />
这样是不是简单多了?
遍历组件并进行国际化的代码也很简单,基本上就是对VisualTreeHelper的递归调用:
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
LocalizeRecursive(this);
}
void LocalizeRecursive(UIElement elem)
{
GetLocalizer(elem.GetType()).Localizer(elem);
int childCount = VisualTreeHelper.GetChildrenCount(elem);
for (int i = 0; i < childCount; i++)
{
var child = VisualTreeHelper.GetChild(elem, i) as UIElement;
if (child != null)
LocalizeRecursive(child);
}
}
ILocalizer GetLocalizer(Type type)
{
ILocalizer localizer = null;
if (!_localizers.TryGetValue(type, out localizer))
localizer = new NullLocalizer();
return localizer;
}
static void RegisterLocalizers()
{
_localizers.Add(typeof(TextBlock), new TextBlockLocalizer());
_localizers.Add(typeof(Button), new ButtonLocalizer());
_localizers.Add(typeof(DataGrid), new DataGridLocalizer());
}
几种Localizer的代码因为涉及到一些业务上的东西这里就不给出了,基本上无非就是字符串的查找替换而已。
这样处理以后,界面的XAML代码变得比以前整洁多了。
<TextBlock Text="{Binding alabel, Source={StaticResource myStrings}}" />
如果界面上每个文本部分都要手工输入这么长串东西,迟早得把写代码的人搞疯掉。就算真的有毅力全部输入,这么一大坨的XAML对看代码的人无疑也是一种折磨。附带一提,有些文章提出的国际化方案似乎意犹未尽,在Binding后面还要再加上一个ConvertParameter,难道这些人对裹脚布有特殊的偏好?
我在项目中为了减少国际化的工作量,同时也为了让代码变得干净清爽一点,采用了另外一种基于约定的国际化方案。其实背后的道理说穿不值一文钱,就是让界面上所有待翻译的文字输入时遵循一定的格式,比如“rs:alabel”,程序使用VisualTreeHelper这个方便的类遍历界面上所有组件,找到所有符合规则的文字,然后翻译成对于当前语言的内容。这个方案简单而且工作得很好,因为我们的界面中需要国际化的部分90%以上不脱TextBlock、Button和DataGrid这三种组件,如果有特殊的控件不能用此方式进行国际化也没有关系,毕竟绝大部分工作都能够很简单的完成了。
换言之,现在添加控件的时候只要这样写:
<TextBlock Text="rs:alabel" />
这样是不是简单多了?
遍历组件并进行国际化的代码也很简单,基本上就是对VisualTreeHelper的递归调用:
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
LocalizeRecursive(this);
}
void LocalizeRecursive(UIElement elem)
{
GetLocalizer(elem.GetType()).Localizer(elem);
int childCount = VisualTreeHelper.GetChildrenCount(elem);
for (int i = 0; i < childCount; i++)
{
var child = VisualTreeHelper.GetChild(elem, i) as UIElement;
if (child != null)
LocalizeRecursive(child);
}
}
ILocalizer GetLocalizer(Type type)
{
ILocalizer localizer = null;
if (!_localizers.TryGetValue(type, out localizer))
localizer = new NullLocalizer();
return localizer;
}
static void RegisterLocalizers()
{
_localizers.Add(typeof(TextBlock), new TextBlockLocalizer());
_localizers.Add(typeof(Button), new ButtonLocalizer());
_localizers.Add(typeof(DataGrid), new DataGridLocalizer());
}
几种Localizer的代码因为涉及到一些业务上的东西这里就不给出了,基本上无非就是字符串的查找替换而已。
这样处理以后,界面的XAML代码变得比以前整洁多了。
相关文章推荐
- Windows phone 7 高级编程——使用visual stdio 、silverlight与XNA进行应用和游戏开发
- 使用 Expression Blend 2对一个Silverlight Twitter应用进行样式化
- 抛砖引玉:使用docker对Meteor应用进行产品级部署(入门篇)
- [源码解读]Silverlight 4 中对不规则对象进行碰撞检测(在游戏中常使用的是否碰撞怪物边界等原理)
- 一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇-演示ORM的批量删除与更新
- Spring - Java/J2EE Application Framework 应用框架 第 11 章 使用ORM工具进行数据访问
- Spring入门学习——使用应用事件进行通信
- ASP.NET页面进行GZIP压缩优化的几款压缩模块的使用简介及应用测试!(附源码)
- 使用Process进行DOS命令交互的简单应用
- 一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇阶段总结与WinForm篇展望
- SpringCloud系列九:SpringCloudConfig 基础配置(SpringCloudConfig 的基本概念、配置 SpringCloudConfig 服务端、抓取配置文件信息、客户端使用 SpringCloudConfig 进行配置、单仓库目录匹配、应用仓库自动选择、仓库匹配模式)
- 一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-实例一个模块(商品字典)
- SilverLight企业应用框架设计【五】客户端调用服务端(使用JSON传递数据,自己实现RESTful Web服务)
- 【Silverlight】Bing Maps开发应用与技巧六:使用样式美化图钉(Pushpin)控件的ToolTip外观 推荐
- 【使用PushSharp进行IOS发布应用的消息推送】
- Jboss应用使用jconsole进行性能监测及内存溢出
- wicket基础应用(1)--使用wicket对表单中的数据进行验证
- docker应用-5(使用overlay 网络进行容器间跨物理主机通信)
- 【Silverlight】限制Silverlight应用只能在指定的域名下使用,保护你的SL程序
- 使用python进行新浪微博应用开发