国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Caliburn.Micro學習筆記(四)----IHandle<T>實現多語言功能

2019-11-11 02:50:22
字體:
來源:轉載
供稿:網友

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

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 开江县| 东丰县| 历史| 西盟| 拜泉县| 曲靖市| 合江县| 南靖县| 喀喇沁旗| 沈阳市| 柯坪县| 新宾| 温泉县| 皋兰县| 莒南县| 东丰县| 安宁市| 镶黄旗| 康马县| 绍兴县| 西安市| 且末县| 涿鹿县| 保靖县| 都江堰市| 镇赉县| 庐江县| 潮州市| 沙雅县| 体育| 元氏县| 太仆寺旗| 天台县| 永州市| 龙门县| 阳朔县| 潼南县| 翼城县| 如东县| 大竹县| 沂水县|