Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能
说一下IHandle<T>实现多语言功能
因为Caliburn.Micro是基于MvvM的UI与codebehind分离,
binding可以是双向的所以我们想动态的实现多语言切换很是方便今天我做一个小demo给大家提供一个思路
先看一下效果
点击英文 变成英文状态点chinese就会变成中文
源码的下载地址在文章的最下边
多语言用的是资源文件建一个MyLanguage的资源文件再添加一个MyLanguage.en-US的资源文件如果你还想要
其它的语言可自己添加。两个资源文件里写上你要的文本如下图这样,它们的名称是一样的只是值一个是中文一个是英文
下面我们就要开始用Caliburn.Micro的IHandle<T>去实现多语言了
先写一个资源的接口
- public interface IResource
- {
- string GetString(string name);
- CultureInfo CurrentCulture { set; }
- }
- public interface IResourceTask
- {
- void ChangeLanguage(string language);
- string GetString(string name);
- event EventHandler LanguageChanged;
- }
IResource接口是资源要实现的,GetString(stirng name)方法是得到根据名字得到资源里的值
CurrentCulture是中英文语言转换的
ResourceTask接口是一个管理接口它管理资源的我们通过它去实现
语言转换时把发送广播把页面上的所有文字转换成想要的语言。
再写一个简单的信息接口,也就是我们发送广播时的数据格式
- public interface IMessage
- {
- }
- public class LanguageChangedMessage : IMessage
- {
- }
LanguageChangedMessage就是我们要发送广播的数据格式
下面就来实现一下IResourceTask接口
- public class ResourceTask : IResourceTask
- {
- public ResourceTask()
- {
- System.Data.DataTable _dt = new System.Data.DataTable();
- }
- [ImportMany]
- public IResource[] Resources { get; set; }
- public void ChangeLanguage(string language)
- {
- CultureInfo culture = new CultureInfo(language);
- Thread.CurrentThread.CurrentCulture = culture;
- Thread.CurrentThread.CurrentUICulture = culture;
- Resources.Apply(item => item.CurrentCulture = culture);
- IEventAggregator eventAggregator = IoC.Get<IEventAggregator>();
- eventAggregator.Publish(new LanguageChangedMessage());
- if (LanguageChanged != null)
- {
- LanguageChanged(this, null);
- }
- }
- public event EventHandler LanguageChanged;
- public string GetString(string name)
- {
- string str = null;
- foreach (var resource in Resources)
- {
- str = resource.GetString(name);
- if (str != null)
- {
- break;
- }
- }
- return str;
- }
- }
通过Resources得到所有export IResource的类
ChangeLanguage(string language)方法里的
Resources.Apply(item => item.CurrentCulture = culture);是把所有实现IResult类的CurrentCulture修改成我们要换成的语言格式
eventAggregator.Publish(new LanguageChangedMessage()); 就是去发送广播,把页面上所有的的文字切换
EventHandler LanguageChanged;事件是如果我们还想切换完语言后做一些事件就可以写在这个事件里
再写一个实现 IResult的类
- [Export(typeof(IResource))]
- [PartCreationPolicy(CreationPolicy.NonShared)]
- public class MyResource : IResource
- {
- private ResourceManager stringResource;
- private CultureInfo culture = new CultureInfo("zh-cn");
- public CultureInfo CurrentCulture
- {
- get
- {
- return culture;
- }
- set
- {
- culture = value;
- }
- }
- public MyResource()
- {
- stringResource = new ResourceManager("WPFMultLanguage.Resource.MyLanguage", typeof(MyResource).Assembly);
- }
- public string GetString(string name)
- {
- return stringResource.GetString(name, culture);
- }
- }
ResourceManager 可以对我们前边写的两种语言的资源文件的读写
在类初始化的时候我们给出资源文件的路径
在GetString(string name)里我们就可以通过ResourceManager根据当前的culture去读取资源文件里的字符了
接下来的问题就是我们怎么去通过接收广播把页面上把文字切换
我们写一个 XAML 标记扩展类
- public class MyResourceExtension : MarkupExtension, INotifyPropertyChanged, IHandle<LanguageChangedMessage>
- {
- public string Key
- {
- get;
- set;
- }
- public string Value
- {
- get
- {
- if (Key == null)
- {
- return null;
- }
- IResourceTask result = IoC.Get<IResourceTask>();
- string s = result.GetString(Key);
- return s;
- }
- }
- public MyResourceExtension()
- {
- if (!Execute.InDesignMode)
- {
- IoC.Get<IEventAggregator>().Subscribe(this);
- }
- }
- public event PropertyChangedEventHandler PropertyChanged;
- public void PropertyChanted()
- {
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs("Value"));
- }
- }
- public override object ProvideValue(IServiceProvider serviceProvider)
- {
- IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
- Binding binding = new Binding("Value") { Source = this, Mode = BindingMode.OneWay };
- return binding.ProvideValue(serviceProvider) as BindingExpression;
- }
- public void Handle(LanguageChangedMessage message)
- {
- PropertyChanted();
- }
- }
这个类我们要实现MarkupExtension基类这样我们才能把我们的类可以在xmal里标识出来
我们要重写一下ProvideValue(IServiceProvider serviceProvider)方法这里我们是要把Value双向绑定到页面上
这个类实现了还INotifyPropertyChanged和IHandle<LanguageChangedMessage>接口
这两个类能干什么我想你们应该都知道吧一个是用来binging的一个是用来接收消息的
Key就是我资源文件里的名称项
value是资源文件里的值项看一下它的get也可以看来出是通过IResourceTask的getstring把值取出来
接口信息的方法Handle(LanguageChangedMessage message)
只要有消息过来我们就PropertyChanged Value值这样就可以 把字符切换了,
我们再看一下前台页面是怎么处理的
- <Window x:Class="WPFMultLanguage.Views.MyView"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:local="clr-namespace:WPFMultLanguage.Command"
- xmlns:cal="http://www.caliburnproject.org"
- cal:Message.Attach="[Event Loaded]=[Action LoadEvent($source)]"
- Title="MyView" Height="" Width="">
- <StackPanel>
- <Menu>
- <MenuItem Header="{local:MyResource Key=英文}" cal:Message.Attach="[Event Click]=[Action ChanguageLanguage('en')]"></MenuItem>
- <MenuItem Header="{local:MyResource Key=中文}" cal:Message.Attach="[Event Click]=[Action ChanguageLanguage('zh')]"></MenuItem>
- </Menu>
- <TextBlock Text="{local:MyResource Key=语言}"/>
- <Button Content="{local:MyResource Key=你好}"/>
- <TextBox x:Name="tb_Show" Text="{local:MyResource Key=文本}"></TextBox>
- <TextBox x:Name="tb_Load" Text="{local:MyResource Key=文本2}"></TextBox>
- </StackPanel>
- </Window>
xmlns:local="clr-namespace:WPFMultLanguage.Command"
这样是把我们上边写的的xaml扩展类放到页面上 Header="{local:MyResource Key=英文}"
这样每一个控件都会初始化一个MyResourceExtension类都会去订阅IHandle<LanguageChangedMessage>广播
再看一下viewModel
- namespace WPFMultLanguage.ViewModels
- {
- [Export(typeof(IShell))]
- public class MyViewModel :Screen
- {
- public MyViewModel()
- {
- }
- public void LoadEvent(object obj)
- {
- //var res = IoC.Get<IResourceTask>();
- //((MyView)GetView()).tb_Load.Text = res.GetString("文本2");
- }
- public void ChanguageLanguage(string lan)
- {
- var res = IoC.Get<IResourceTask>();
- switch (lan)
- {
- case "zh":
- res.ChangeLanguage("zh-CN");
- break;
- case "en":
- res.ChangeLanguage("en-US");
- break;
- }
- }
- }
- }
Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能的更多相关文章
- Caliburn.Micro学习笔记目录
Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 Caliburn.Micro学习笔记(二)----Actions Caliburn.Micro学习笔记(三)----事件聚合IE ...
- Caliburn.Micro学习笔记目录——li-peng
Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 Caliburn.Micro学习笔记(二)----Actions Caliburn.Micro学习笔记(三)----事件聚合IE ...
- Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 Ihandle<T>
Caliburn.Micro学习笔记目录 今天 说一下Caliburn.Micro的IEventAggregator和IHandle<T>分成两篇去讲这一篇写一个简单的例子 看一它的的实现 ...
- Caliburn.Micro学习笔记(一)----引导类和命名匹配规则
Caliburn.Micro学习笔记目录 用了几天时间看了一下开源框架Caliburn.Micro 这是他源码的地址http://caliburnmicro.codeplex.com/ 文档也写的很详 ...
- Caliburn.Micro学习笔记(二)----Actions
Caliburn.Micro学习笔记目录 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions, ...
- Caliburn.Micro学习笔记(五)----协同IResult
Caliburn.Micro学习笔记目录 今天说一下协同IResult 看一下IResult接口 /// <summary> /// Allows custom code to execu ...
- Caliburn.Micro学习笔记目录——Zhouyongh
解析Caliburn.Micro(一) 解析Caliburn.Micro(二) 解析Caliburn.Micro(三) 解析Caliburn.Micro(四) Illusion = Caliburn. ...
- Caliburn micro 学习笔记...
页面跳转 LLS 结合 CM 使用方法 事件处理
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
随机推荐
- jQuery Ion.Calendar 日期/日历
在线实例 实例演示 默认 实例演示 每周第一天 实例演示 输入框插件 实例演示 HTML data 属性 实例演示 回调函数1 实例演示 回调函数2 使用方法 <div id="cal ...
- Android开发1:基本UI界面设计——布局和组件
前言 啦啦啦~本学期要开始学习Android开发啦~ 博主在开始学习前是完完全全的小白,只有在平时完成老师要求的实验的过程中一步一步学习~从此篇博文起,博主将开始发布Android开发有关的博文,希望 ...
- 基本动画CABasicAnimation - 完成之后闪回初始状态
基本动画CABasicAnimation 结束之后,默认闪回初始状态,那怎么解决呢? position需要设备两个属性: // MARK: - 结束后不要闪回去 anim.removedOnCompl ...
- android doc里面adb连接出现问题的解决方法
第一保证连接的两边都是有网的 第二 就是网上常说的1.adb kill-server 2.adb start-server 3.adb remount 但是在运行adb remount有可能会提示 ...
- Git 简易手册
前言 这里就不介绍 git 了,表一看到命令行就怕怕,常用的命令也就这些,基本满足 99% 以上的项目需求,非常实用. 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnbl ...
- iOS 实现转盘的效果
效果 #import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBO ...
- Java调用solrj5.5.3接口,查询数据
前期准备 搭建solr服务 参考上一篇,搭建solr搜索服务. 添加依赖 maven工程的话,添加如下依赖, <!-- https://mvnrepository.com/artifact/or ...
- js自动完成
源代码来自于: http://down.51cto.com/data/921955 我做了一下修改. 要做一个自动完成的功能,又不想依赖一大堆的js脚本库,我要的是定制的,代码尽可能简洁,方便修改和 ...
- 有氧运动 && 无氧运动
有氧运动也叫做有氧代谢运动,是指人体在氧气充分供应的情况下进行的体育锻炼.有氧运动的好处是:可以提升氧气的摄取量,能更好地消耗体内多余的热量.也就是说,在运动过程中,人体吸入的氧气与需求相等,达到生理 ...
- MySQL如何导出带日期格式的文件
一网友问在MySQL中如何只用SQL语句导出带日期格式的文件.觉得有点意思,于是尝试了一下.导出文件使用SELECT INTO OUTFILE 但是OUTFILE后面的值不能使用变量,所以只能使用动态 ...