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真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
随机推荐
- JS学习笔记9之event事件及其他事件
-->鼠标事件-->event事件对象-->默认事件-->键盘事件(keyCode)-->拖拽效果 一.鼠标事件 onclick ---------------鼠标点击事 ...
- autocomplete="off" 不起作用
首先来了解一下 表单自动填充的原理,当我们登录的时候,如果选择的记住登录密码,那么后续界面中如果有 <input type="text" name="field1& ...
- 自己实现苹果安装app动画
最近在学习CALayer相关动画,然后某一天突然发现苹果安装app这动画就很不错啊,所以就想自己实现下. 具体效果如图: 还是不试不知道一试吓一跳啊,这看上去简单的动画没我想象的那么简单. 首先这个动 ...
- asp.netDataTable导出excel方法(1)
先来写一段代码,这段代码也是我在网上找的,但是他那个原先有点问题,我对他那个进行了修改,现在这个代码是我修改改过的,应该没有问题的. public int StreamExport(System.Da ...
- SJPullDownMenu下拉菜单框架使用
SJPullDownMenu 快速集成类似淘宝筛选下拉菜单 如果页面显示不全等问题请转至:http://www.jianshu.com/p/d07c6393830c 查看使用 Getting Star ...
- MRC下多个对象的内存管理
//set方法传递进来对象的生命周期,要求是在当前对象销毁之前,它一直存在就好- (void)setCar:(Car *)car{ //1.判断set方法传递进来的值是否与成员变量中保存的是同一个对象 ...
- AFNetWorking https请求 SSL认证 自制证书
1.服务器会给一个证书,一般为.pem格式证书 2.将.pem格式的证书转换成.cer格式的证书 打开电脑自带终端 ,进入到桌面 cd Desktop 回车回到桌面Desktop Admin$ 输入 ...
- active_record的不定时更新
1 valid?方法只是校验所有的校验条件,如果规则A仅加在数据库上,而不是model上,是不对校验起作用的,最后提交时虽然校验成功,但仍然会抛异常.比如数据库中增加了非空的规则,但模型上没有pres ...
- Visual Studio 2013 Update 2 RTM 发布
今天,微软再Visual Studio Blog发布了开放Visual Studio 2013 Update 2 RTM 下载的文章. 原来安装RC版本的同志们可以直接安装,提供在线安装和ISO下载安 ...
- Linux启动报错missing operating system
用UltraISO制作了一个Red Hat Enterprise Linux Server release 5.7系统的U盘启动盘,然后在一台PC上安装,由于安装过程中在干别的事情,有些选项没有细看. ...