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

简介:

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="300" Width="300">
    <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

 本文转自lpxxn博客园博客,原文链接:http://www.cnblogs.com/li-peng/p/3433974.html,如需转载请自行联系原作者

相关文章
|
自然语言处理 安全 Java
Google Tink多语言跨平台加密演示
Google Tink多语言跨平台加密演示
481 0
|
2月前
|
存储 缓存 JSON
10款好用的开源 HarmonyOS 工具库
HarmonyOS NEXT 正式版即将发布,你在学习鸿蒙的过程还有哪些好用的工具库吗,欢迎分享给V 哥,关注威哥爱编程,一起学习鸿蒙开发。
|
6月前
|
定位技术 API C#
.NET开源、功能强大、跨平台的图表库
.NET开源、功能强大、跨平台的图表库
|
3月前
|
存储 并行计算 数据处理
跨语言集成:Dask 与其他编程环境的交互
【8月更文第29天】Dask 是一个开源的并行计算库,旨在为 Python 社区提供高性能的并行计算能力。尽管 Dask 主要在 Python 生态系统中使用,但它也可以与其他编程语言环境(如 R 和 Julia)进行交互,实现跨语言的数据处理。本文将探讨如何利用 Dask 与 R 和 Julia 等其他语言集成,以便在不同编程环境中共享数据和计算资源。
79 4
|
6月前
|
存储 自然语言处理 监控
【Unity 实用工具篇】| 游戏多语言解决方案,官方插件Localization 实现本地化及多种语言切换
Unity的多语言本地化是一个很实用的功能,它可以帮助游戏支持多种语言,让不同语言的玩家都能够更好地体验游戏。 而实现本地化的方案也有很多种,各个方案之间也各有优劣,后面也会对多个方案进行介绍学习。 本文就来介绍一个专门作用于多语言本地化的Unity官方插件:Localization 。 这个插件方便进行游戏的多语言本地化,让游戏支持多种语言,下面就来看看该插件的使用方法吧!
|
开发框架 自然语言处理 前端开发
一个基于.NetCore开发、模块化、跨平台、多语言商城系统
一个基于.Net Core MVC开发的、简单、模块化、跨平台、多语言的电子商务系统。项目采用模块化架构,代码清晰,便于扩展;功能完善、集成了外贸常见的支付方式;支持多个主题切换;所采用的技术栈都是最新的。
379 0
一个基于.NetCore开发、模块化、跨平台、多语言商城系统
|
自然语言处理 架构师 开发者
多语言|学习笔记
快速学习多语言。
105 0
多语言|学习笔记
|
自然语言处理 开发者
多语言| 学习笔记
快速学习多语言。
|
IDE 开发工具 C#
Visual Studio 2022 Preview 2 发布:扩展跨平台功能,支持实时预览,debug 更高效
Visual Studio 2022 Preview 2 发布:扩展跨平台功能,支持实时预览,debug 更高效
1010 0
Visual Studio 2022 Preview 2 发布:扩展跨平台功能,支持实时预览,debug 更高效
|
编译器 C语言
QT应用编程: QtCreate编译部署开源音视频框架模块QtAV
QT应用编程: QtCreate编译部署开源音视频框架模块QtAV
204 0
QT应用编程: QtCreate编译部署开源音视频框架模块QtAV