WPF本地化(多语言)语言解决方案

来源:互联网 发布:imf的数据 编辑:程序博客网 时间:2024/05/16 12:06


工程目录结构:


LocalizedLangExtension.cs

using System;using System.Collections.Generic;using System.ComponentModel;using System.Diagnostics;using System.Globalization;using System.Linq;using System.Resources;using System.Text;using System.Threading;using System.Windows;using System.Windows.Data;using System.Windows.Markup;namespace LocalizedLangTest.Util.Localization{    [MarkupExtensionReturnType(typeof(BindingExpression))]    public class LocalizedLangExtension : MarkupExtension, INotifyPropertyChanged    {        public event PropertyChangedEventHandler PropertyChanged;        private static bool? DesignMode = null;        private static EventHandler<EventArgs> LocalLanguageChangeEvent;        private static ResourceManager ResourceManager;        private static CultureInfo CurrentCulture = new CultureInfo("en-US");        public LocalizedLangExtension()        {            LocalLanguageChangeEvent += new EventHandler<EventArgs>(LocalLanguageChangedHandler);            Init();        }        public LocalizedLangExtension(string key)            : this()        {            Key = key;        }        public void Init()        {            // 本地化语言资源文件根名            ResourceManager = new ResourceManager("LocalizedLangTest.Resources.String.Resource", typeof(LocalizedLangExtension).Assembly);            // 设置与系统相同的本地语言            string lang = System.Globalization.CultureInfo.CurrentUICulture.Name;            SetLocalLanguage(lang);        }        [ConstructorArgument("key")]        public string Key { get; set; }        private string mDefaultValue;        /// <summary>        /// 默认值,为了使在设计器的情况时把默认值绑到设计器        /// </summary>        public string DefaultValue        {            get => mDefaultValue;            set => mDefaultValue = value;        }        private string mCurrentValue;        /// <summary>        /// 资源的具体内容,通过资源名称也就是上面的Key找到对应内容        /// </summary>        public string CurrentValue        {            /* get */            get            {                /* 如果为设计器模式,本地的资源没有实例化,我们不能从资源文件得到内容,所以从KEY或默认值绑定到设计器去 */                if (IsDesignMode)                {                    return DefaultValue?? Key?? "Error";                }                else                {                    if (null != Key)                    {                        return GetString(Key);                    }                }                return mCurrentValue;            }            /* set */            set => mCurrentValue = value;        }        /// <summary>        /// 语言改变通知事件        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void LocalLanguageChangedHandler(object sender, EventArgs e)        {            // 通知CurrentValue值已经改变,需重新获取            if (null != PropertyChanged)            {                PropertyChanged(this, new PropertyChangedEventArgs(nameof(CurrentValue)));            }        }        /// <summary>        /// 返回一个表达式对象,即绑定结果        /// </summary>        /// <param name="serviceProvider">serviceProvider是一个依赖解析器,你可以使用它来获取一个命名IProvideValueTarget的服务,然后会被用来获取属性的MarkupExtension (你可以得到它的目标对象)的目标。</param>        /// <returns></returns>        public override object ProvideValue(IServiceProvider serviceProvider)        {            IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;            Setter setter = target.TargetObject as Setter;            if (setter != null)            {                string ss = setter.TargetName;                return new Binding(nameof(CurrentValue)) { Source = this, Mode = BindingMode.OneWay };            }            else            {                Binding binding = new Binding(nameof(CurrentValue)) { Source = this, Mode = BindingMode.OneWay };                return binding.ProvideValue(serviceProvider);            }        }        /// <summary>        /// 判断是设计器还是程序运行        /// </summary>        public static bool IsDesignMode        {            get            {                if (null == DesignMode)                {                    var prop = DesignerProperties.IsInDesignModeProperty;                    DesignMode = (bool)DependencyPropertyDescriptor.FromProperty(prop, typeof(FrameworkElement)).Metadata.DefaultValue;                    if (!DesignMode.GetValueOrDefault(false)                        && Process.GetCurrentProcess().ProcessName.StartsWith("devenv", StringComparison.Ordinal))                    {                        DesignMode = true;                    }                }                return DesignMode.GetValueOrDefault(false);            }        }        /// <summary>        /// 修改本地语言        /// </summary>        /// <param name="language"></param>        public static void SetLocalLanguage(string language)        {            CultureInfo culture = new CultureInfo(language);            Thread.CurrentThread.CurrentCulture = culture;            Thread.CurrentThread.CurrentUICulture = culture;            CurrentCulture = culture;            if (null != LocalLanguageChangeEvent)            {                LocalLanguageChangeEvent(null, null);            }        }        /// <summary>        /// 根据KEY获取文本        /// </summary>        /// <param name="key"></param>        /// <returns></returns>        public static string GetString(string key)        {            string resault = null;            try            {                resault = ResourceManager?.GetString(key, CurrentCulture);            }            finally            {                resault = resault?? "Error";            }            return resault;        }    }}



资源文件(新建resx的资源文件):

1.英文(默认资源文件)



2. 中文(Resource.zh-CN.resx)

增加一个测试信息

名称:TB_KEY

值为:随便


使用:

MainWindow.xaml:

xmlns:ll="clr-namespace:LocalizedLangTest.Util.Localization"<TextBlock x:Name="tb1" Text="{ll:LocalizedLang TB_KEY}"/>

手动切换语言(MainWindow.xaml.cs):

LocalizedLangExtension.SetLocalLanguage("zh-CN");


根据当前应用设置的语言获取某一个KEY对应的value:

string str = LocalizedLangExtension.GetString("TB_KEY");


原创粉丝点击