Caliburn.Micro学习笔记目录

说一下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;
}
}
}
}

源码:WPFMultLanguageDemo.rar

Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能的更多相关文章

  1. Caliburn.Micro学习笔记目录

    Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 Caliburn.Micro学习笔记(二)----Actions Caliburn.Micro学习笔记(三)----事件聚合IE ...

  2. Caliburn.Micro学习笔记目录——li-peng

    Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 Caliburn.Micro学习笔记(二)----Actions Caliburn.Micro学习笔记(三)----事件聚合IE ...

  3. Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 Ihandle<T>

    Caliburn.Micro学习笔记目录 今天 说一下Caliburn.Micro的IEventAggregator和IHandle<T>分成两篇去讲这一篇写一个简单的例子 看一它的的实现 ...

  4. Caliburn.Micro学习笔记(一)----引导类和命名匹配规则

    Caliburn.Micro学习笔记目录 用了几天时间看了一下开源框架Caliburn.Micro 这是他源码的地址http://caliburnmicro.codeplex.com/ 文档也写的很详 ...

  5. Caliburn.Micro学习笔记(二)----Actions

    Caliburn.Micro学习笔记目录 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions, ...

  6. Caliburn.Micro学习笔记(五)----协同IResult

    Caliburn.Micro学习笔记目录 今天说一下协同IResult 看一下IResult接口 /// <summary> /// Allows custom code to execu ...

  7. Caliburn.Micro学习笔记目录——Zhouyongh

    解析Caliburn.Micro(一) 解析Caliburn.Micro(二) 解析Caliburn.Micro(三) 解析Caliburn.Micro(四) Illusion = Caliburn. ...

  8. Caliburn micro 学习笔记...

    页面跳转 LLS 结合 CM 使用方法 事件处理

  9. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

随机推荐

  1. asp.net mvc 自定义pager封装与优化

    asp.net mvc 自定义pager封装与优化 Intro 之前做了一个通用的分页组件,但是有些不足,从翻页事件和分页样式都融合在后台代码中,到翻页事件可以自定义,再到翻页和样式都和代码分离, 自 ...

  2. 关于arcgis engine的工作空间(IWorkspace)和选择集(FeatureSelection)

    1.通过某个WorkspaceFactoryClass(例如AccessWorkspaceFactoryClass)拿到工作空间工厂接口,这时的OpenFromFile方法可以直接打开mdb类型文件, ...

  3. 写pdf文件

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  4. ArcGIS中的坐标系统定义与投影转换【转】

    ArcGIS中的坐标系统定义与投影转换 坐标系统是GIS数据重要的数学基础,用于表示地理要素.图像和观测结果的参照系统,坐标系统的定义能够保证地理数据在软件中正确的显示其位置.方向和距离,缺少坐标系统 ...

  5. Synchronization Service Manager

    You can use this UI Shell to check the User Profile log for the SharePoint.   It's stored in this pa ...

  6. docker'部署

    环境:ubuntu-14.04.4-server-amd64 1.更换阿里云源 备份源配置文件: $ sudo cp /etc/apt/sources.list /etc/apt/sources.li ...

  7. [Java编程思想-学习笔记]第2章 一切都是对象

    2.1  创建新的数据类型:类 通过第一章掌握了面向对象的理论后,我们知道每个对象必定属于一个类型,那么Java如何创建新的数据类型?如下程序所示: class Circle { // 属性 // 方 ...

  8. [css]我要用css画幅画(六)

    接着之前的[css]我要用css画幅画(五), 由于这个画已经画了很久了,这次一次性加了比较多更新,算是让这幅画告一段落吧. 本次的更新包括: 1. 给云增加动画 2. 画了一棵树 3. 树上画了一个 ...

  9. RunLoop-Custom input source

    Creating Creating a custom input source involves defining the following: The information you want yo ...

  10. Lucene索引文件学习

     最近在做搜索,抽空看一下lucene,资料挺多的,不过大部分都是3.x了--在对着官方文档大概看一下. 优化后的lucene索引文件(4.9.0) 一.段文件 1.段文件:segments_5p和s ...