当前位置:   article > 正文

WPF 动态切换界面语言_wpf多语言

wpf多语言

概述

很多时候,软件都会被要求支持中英文,此时,就需要编程人员对软件进行多语种支持的开发。
解决方案有很多,这里主要介绍通过编辑xaml语言包来实现。
其功能有:

  • 通过设定“ <Application.Resources>”的方式,实现控件动态加载语言
  • 支持动态切换
  • 支持自动加载上一次选定的语言

先来看效果

中英文切换效果

环境说明

当前样例,运行环境是:

  • VS 2022
  • .Net 6
  • WPF
  • C#
  • Windows 11

原则上,windows开发平台均适用。

具体步骤

1. 编辑你的语言包

首选,你需要创建两个语言包,分别是中文、英文的xaml文件。
在这里插入图片描述
它们的文件【属性】,设置为如图:
在这里插入图片描述

2. 编辑语言包内容

我们通过定义key、value来编辑一个字典的xaml文件。
它们的每个“词条”,均为string类型。
以Chinese.xaml 为例,其内容基本如下:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:DeviceToolsKit"
                    xmlns:sys="clr-namespace:System;assembly=mscorlib">

    <!--Common Text Dictionary-->
    <sys:String x:Key="DicText_Common_Tips">提示说明:</sys:String>
    <sys:String x:Key="DicText_Common_Error">错误警告:</sys:String>
    <sys:String x:Key="DicText_Common_Notice">注意事项:</sys:String>

</ResourceDictionary>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

以第一个词条文本举例
它的key名称是"DicText_Common_Tips",我们后面可以通过使用这个名称来调用它的具体文本值。
【提示说明:】这个是"DicText_Common_Tips"的具体文本。

请注意,下方的命名空间是必须添加的

xmlns:sys="clr-namespace:System;assembly=mscorlib"
  • 1

下面附上对应的English.xaml文件

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:DeviceToolsKit"
                    xmlns:sys="clr-namespace:System;assembly=mscorlib">

   
    <!--Common Text Dictionary-->
    <sys:String x:Key="DicText_Common_Tips">Tips:</sys:String>
    <sys:String x:Key="DicText_Common_Error">Error:</sys:String>
    <sys:String x:Key="DicText_Common_Notice">Notice:</sys:String>

</ResourceDictionary>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

通过对比,我们可以发现

  • 中英文字典的Key值名称是一致的,唯一不同的是其对应的文本不同。
  • 因此,这也就基本确定了后续的开发思路:
  •  我们只需要加载需要的xaml文件,然后在需要的地方,使用唯一的keyName就可以了。
    
    • 1

3. 修改App.xaml

 <Application.Resources>

        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <!--Language packages-->
                <ResourceDictionary Source="Resources\Languages\Chinese.xaml"/>
                <ResourceDictionary Source="Resources\Languages\English.xaml"/>
                
        </ResourceDictionary>

    </Application.Resources>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在你的App.xaml文件中,增加上述语言包xaml文件。
此后,它将作为资源,并在程序启动的时候被加载进去。
需要注意的是

  • 语言包的路径,这需要根据你自身项目来确定,我这里是把中英文的语言包放在了项目的Resources\Languages\文件夹下。
  • 原则上,系统会自动采用最后一次加载的语言包,作为默认的语种显示。
  • 因此,我们会在后面通过这个特性,来实现 “即时切换”、“默认加载上次选择的语言”这两个功能。

4. 使用语言包字典的Key

语言包的使用非常简单,只需要在你的UI xaml文件里面,对Text或者Content内容进行DynamicResource 的绑定即可。

 <TextBlock Margin="10,0,0,0" Text="{DynamicResource DicText_Common_Tips}"/>
  • 1

5. 实现动态切换语言

首先,在你项目中,添加一个语言的下拉列表,然后为其后面的按钮或者某个控件,绑定一个切换语言的函数方法。
这个步骤我就不多做赘述了,相信各位能够自己实现。
主要介绍一下动态切换的核心方法:

private void ChangeUILanguage(string targetLanguage)
        {
            List<ResourceDictionary> dictionaryList = new List<ResourceDictionary>();
            foreach (ResourceDictionary dictionary in Application.Current.Resources.MergedDictionaries)
            {
                dictionaryList.Add(dictionary);
            }

            string requestedCulture = @"Resources\Languages\" + targetLanguage + ".xaml";
            var resourceDictionary = dictionaryList.FirstOrDefault(d => d.Source.OriginalString.Equals(requestedCulture));

            if (resourceDictionary != null)
            {
                Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
                Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
            }
            else
            {
                MessageBox.Show("Can not load the language resources.");
                return;
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

前面提过:系统会默认使用最后一次加载的语言包,作为使用的对象。
因此,我们利用这个特性,通过以下步骤可以实现即时切换的目标:

  1. 获取当前App的所有ResourceDictionary资源
  2. 如果你现在想要使用English的xaml语言包,那么就先找到它。
  3. 然后再将其移除ResourceDictionary资源队列
  4. 最后重新将其添加
  5. 此时,系统便会使用“最新加载的资源”。

6. 自动加载上次选择的语言包

步骤1:添加App.config文件

向你的项目中,添加App.config文件
然后添加如下的字段:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<appSettings>
		<add key="Language" value="Chinese" />
	</appSettings>
</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

步骤2:重写OnStartup方法

展开App.xaml,编辑App.xaml.cs文件
在这里插入图片描述
添加并修改如下内容

    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);


            List<ResourceDictionary> dictionaryList = new List<ResourceDictionary>();
            foreach (ResourceDictionary dictionary in Application.Current.Resources.MergedDictionaries)
            {
                dictionaryList.Add(dictionary);
            }
            var targetLanguage = ConfigurationManager.AppSettings["Language"];

            if (targetLanguage == null)
                targetLanguage = "English";

            string requestedCulture = @"Resources\Languages\" + targetLanguage + ".xaml";
            var resourceDictionary = dictionaryList.FirstOrDefault(d => d.Source.OriginalString.Equals(requestedCulture));

            if(resourceDictionary!=null)
            {
                Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
                Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
            }
            else
            {
                MessageBox.Show("Can not find the language resources.");
                return;
            }

        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

这段代码中,我们会先行读取config的language值,然后将其作为目标,找到并重新加载对应的语言包。

步骤3:添加修改App.config 的方法

这个方法,你可以将它添加在需要的地方。
一般是把它放在选择语言的界面,也就是实现语言即时切换的地方。

  private void UpdateAppConfigLanguageSetting(string valueStr)
        {
            Configuration _configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            _configuration.AppSettings.Settings["Language"].Value = valueStr;
            _configuration.Save();
            ConfigurationManager.RefreshSection("appSettings");
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

其中

 ConfigurationManager.RefreshSection("appSettings");
  • 1

这句刷新config section的方法是必须的。

总结

上述方法适用于中小型项目。
在大型项目中,建议使用其他资源消耗更少的方法来提升性能。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/427818
推荐阅读
相关标签
  

闽ICP备14008679号