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


工程目录结构:


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");


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OneOnce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值