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真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
随机推荐
- asp.net mvc 中 一种简单的 URL 重写
asp.net mvc 中 一种简单的 URL 重写 Intro 在项目中想增加一个公告的功能,但是又不想直接用默认带的那种路由,感觉好low逼,想弄成那种伪静态化的路由 (别问我为什么不直接静态化, ...
- iOS 字号转换问题
一,ps和pt转换 px:相对长度单位.像素(Pixel).(PS字体) pt:绝对长度单位.点(Point).(iOS字体) 公式如下: pt=(px/96)*72. 二,字体间转换 1in = 2 ...
- MyEclipse 2016 CI 4新增BootStrap模板
Live Preview with CodeLive 目前CodeLive还只有Live Preview这一个功能,在后续的版本中会陆续添加新功能. 新增Bootstrap模板 在模板面板中选择相应的 ...
- 【转】Linux 初始化 init 系统 [sysvinit systemd upstart]
http://www.ibm.com/developerworks/cn/views/linux/libraryview.jsp?sort_by=&show_abstract=true& ...
- iOS之2016面试题一
序言 招聘高峰期来了,大家都非常积极地准备着跳槽,那么去一家公司面试就会有一堆新鲜的问题,可能不会,也可能会,但是了解不够深.本篇文章为群里的小伙伴们去宝库公司的笔试题,由笔者整理并提供笔者个人参考答 ...
- iOS--UICollectionView(滚动视图)入门
UICollectionView @interface UICollectionView : UIScrollView UICollectionView 和UICollectionViewCon ...
- Linux rm删除大批量文件
在使用rm删除大批量文件时,有可能会遭遇"参数列太长"(Argument list too long)的问题.如下所示 [oracle@DB-Server bdump]$ rm - ...
- CentOS7 虚拟机搭建、初始设置、简单使用
注:虚拟机安装的系统是CentOS7 1.网络设置 网络的设置主要是为了让虚拟机和物理机能够相互ping通,这样就可以用XShell之类的工具操控,也可以上网 见另一篇 CentOS7网络配置 2.物 ...
- nodejs中stream相关资料
nodejs中流(stream)的理解 nodejs stream 手册完整中文版本 nodejs stream详细使用介绍
- 关于java中MessageFormat.format中单引号问题
我们知道java中可以用MessageFormat.format来格式化字符串.这个方法在我们的实际开发中经常用到,有点类似模板,这样我们就不需要用很恶心的拼接字符串了.如下面 String s1=& ...