Caliburn.Micro学习笔记(四)----IHandle实现多语言功能

时间:2023-01-26 16:02:52

Caliburn.Micro学习笔记目录

说一下IHandle<T>实现多语言功能

因为Caliburn.Micro是基于MvvM的UI与codebehind分离,

binding可以是双向的所以我们想动态的实现多语言切换很是方便今天我做一个小demo给大家提供一个思路

先看一下效果

点击英文  变成英文状态点chinese就会变成中文

Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能                        Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能

源码的下载地址在文章的最下边

多语言用的是资源文件建一个MyLanguage的资源文件再添加一个MyLanguage.en-US的资源文件如果你还想要

其它的语言可自己添加。两个资源文件里写上你要的文本如下图这样,它们的名称是一样的只是值一个是中文一个是英文

Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能

下面我们就要开始用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&period;Micro学习笔记目录

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

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

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

  3. Caliburn&period;Micro学习笔记&lpar;三&rpar;----事件聚合IEventAggregator和 Ihandle&lt&semi;T&gt&semi;

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

  4. Caliburn&period;Micro学习笔记&lpar;一&rpar;----引导类和命名匹配规则

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

  5. Caliburn&period;Micro学习笔记&lpar;二&rpar;----Actions

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

  6. Caliburn&period;Micro学习笔记&lpar;五&rpar;----协同IResult

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

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

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

  8. Caliburn micro 学习笔记&period;&period;&period;

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

  9. C&num;可扩展编程之MEF学习笔记&lpar;四&rpar;:见证奇迹的时刻

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

随机推荐

  1. 让Android支持透明状态栏

    <style name="Theme.Timetodo" parent="@android:style/Theme.Holo.Light"> &lt ...

  2. 希尔排序&lpar; Shell Sort&rpar;

    原文地址:http://www.stoimen.com/blog/,在此感谢作者! Insertion sort is a great algorithm, because it’s very int ...

  3. 表结构导出到excel中

    SELECT 表名 = case when a.colorder=1 then d.name else '' end, 表说明 = case when a.colorder=1 then isnull ...

  4. list map vector set 常用函数列表

    #include <stdio.h> #include <iostream>//cin,cout #include <sstream>//ss transfer. ...

  5. javascript 汉字生成拼音

    在网上下载的一个汉字生成拼音的js,很有用,大家一起分享! var PinYin = {"a":"/u554a/u963f/u9515","ai&qu ...

  6. HTTP学习笔记4-请求与响应结构例子

    18,HTTP消息由客户端到服务器的请求和服务器到客户端的响应组成.请求消息和响应消息都是由开始行,消息报头(可选的),空行(只有CRLF的行),消息正文(可选的)组成. 19,对于请求消息,开始行就 ...

  7. 每日一dp&lpar;2&rpar;——龟兔赛跑(hdu 2059)

    比較经典的动态规划的题目了 一般动态规划的想法都是先推断是否有最优子结构,无后效性.接着从状态转移入手,尽量细分状态(即给定N得到N+1),完了再递推计算 难点:转移方程,其一般也难在怎样描写叙述一个 ...

  8. ORACLE ROWNUM解析

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp53 [align=middle;" align="le ...

  9. Python运算符之翩若惊鸿,婉若游龙

    python中的运算符算术运算符:主要用于两个对象算数计算(加减乘除等运算)比较运算符:用于两个对象比较(判断是否相等.大于等运算)赋值运算符:用于对象的赋值,将运算符右边的值(或计算结果)赋给运算符 ...

  10. Python实现登陆的功能

    import datetimetoday=datetime.datetime.today()# 获取当前时间for i in range(3): username=input("请输入用户名 ...