dotnetcore3.1 WPF 实现多语言

Intro

最近把 DbTool 从 WinForm 迁移到了 WPF,并更新到了 dotnet core 3.1,并实现了基于 Microsoft.Extensions.Localization 实现了基本的多语言支持。下面来分享一下如何来实现

服务注册

如果不熟悉如何在 WPF 中使用依赖注入,可以参考上一篇文章 dotnetcore3.1 WPF 中使用依赖注入

在应用启动前注册 Localization 服务,我这里使用的是自己自定义的基于 JSON 的多语言服务

services.AddJsonLocalization(options => options.ResourcesPathType = ResourcesPathType.CultureBased);

服务注册的最后使用了一个 ServiceLocator 模式的代码(DependencyResolver),保存了所有的注册服务,后面的 Localizer 扩展会用到

DependencyResolver.SetDependencyResolver(services);

代码文件实现方式

代码文件(如:MainWindow.xaml.cs) 中实现多语言较为简单,直接注入 IStringLocalizer 即可,获取对应的要实例化的,比如:

public partial class MainWindow: Window
{
private readonly IStringLocalizer<MainWindow> _localizer;
public MainWindow(
IStringLocalizer<MainWindow> localizer)
{
InitializeComponent(); _localizer = localizer;
}
// ...
{
// ...
MessageBox.Show(_localizer["Success"], _localizer["Tip"]);
}
}

xaml 实现方式

LocaliazerExtension

xaml 文件中使用需要自定义一个扩展,定义如下,【实现源码】

public class LocalizerExtension : MarkupExtension
{
private readonly IStringLocalizerFactory _localizerFactory;
public string Key { get; } public LocalizerExtension(string key)
{
Key = key;
_localizerFactory = DependencyResolver.Current.
ResolveService<IStringLocalizerFactory>();
} public override object ProvideValue(IServiceProvider serviceProvider)
{
var targetRootType = serviceProvider.GetType()
.GetProperty("System.Xaml.IRootObjectProvider.RootObject", BindingFlags.Instance | BindingFlags.NonPublic)
?.GetValue(serviceProvider)
?.GetType();
if (null == targetRootType)
{
targetRootType = typeof(MainWindow);
} var localizer = _localizerFactory.Create(targetRootType);
var value = localizer[Key];
return (string)value;
}
}

这里使用到了上面提到的 ServiceLocator 模式的代码,从 DependencyResolver 获取注册的服务,感觉这里的实现需要优化,有更好想法的小伙伴还望一起交流一下,另外如果你的应用比较简单,我觉得上面代码里的通过反射获取 targetRootType 的代码可以直接使用某一个类型例如:typeof(MainWindow) ,这样会更高效

在 xaml 中使用

  1. Window 标签中添加扩展对应的命令空间,例如: xmlns:loc="clr-namespace:DbTool.Localization"
  2. 在需要实现多语言的地方引用,例如:<TextBlock Margin="0,0,4,0" Text="{loc:Localizer DbConnectionString}"></TextBlock>
  3. 在对应的资源文件中配置要使用多语言资源,如上面的 DbConnectionString
<Window x:Class="DbTool.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:loc="clr-namespace:DbTool.Localization"
mc:Ignorable="d"
Title="DbTool" Height="450" Width="800" FontSize="14">
<Grid>
<TextBlock Margin="0,0,4,0" Text="{loc:Localizer DbConnectionString}"></TextBlock>
</Grid>
</Window>

语言切换

发生语言切换时或应用启动时设置默认语言时,要更新当前线程的 Culture 信息

// set current culture
var defaultCulture = "zh";
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(defaultCulture);
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(defaultCulture);

实现效果

More

这种方式的实现,目前还需要重启之后界面的语言才会发生变化,可以进一步优化,实现动态多语言,修改语言之后界面就切换,目前不是太需要,暂时没做,有需要的可以先自己研究一下。

Reference

dotnetcore3.1 WPF 实现多语言的更多相关文章

  1. dotnetcore3.1 WPF 中使用依赖注入

    dotnetcore3.1 WPF 中使用依赖注入 Intro 在 ASP.NET Core 中默认就已经集成了依赖注入,最近把 DbTool 迁移到了 WPF dotnetcore 3.1, 在 W ...

  2. WPF 实现多语言支持

    WPF 多语言有各种实现方式.如 https://www.codeproject.com/Articles/35159/WPF-Localization-Using-RESX-Files,后来发现这个 ...

  3. WPF国际化(多语言)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  4. 设置 WPF 的全球化语言

    https://stackoverflow.com/questions/7454024/setting-culture-en-in-globally-in-wpf-app Thread.Current ...

  5. WPF使用X:Static做多语言支持

    让程序支持多语言,一般把需要显示的字符串保存在一个资源类的static属性中. <!--[if !supportLists]--> <!--[endif]--> 微软的WPF程 ...

  6. WPF 获得当前输入法语言区域

    原文:WPF 获得当前输入法语言区域 本文告诉大家如何获得 WPF 输入法的语言区域 需要使用 user32 的方法,很简单,请看下面 [DllImport("user32.dll" ...

  7. [No000012C]WPF(4/7)类型转换器和标记扩展[译]

    介绍 之前讨论了WPF的基础架构,然后逐步开始学习布局面板,转换,介绍了不同的控件,容器,UI转换等.在这篇文章中,我将讨论每个创建XAML应用前的开发人员应该了解的关于XAML最重要的东西. 标记扩 ...

  8. WPF入门(三)->几何图形之线条(LineGeometry)

    原文:WPF入门(三)->几何图形之线条(LineGeometry) 前一章我们对wpf的xaml语言有了一定的了解,那么我们现在开始来学习如何使用wpf来画出几何图形. LineGeometr ...

  9. 2019-6-23-WPF-获得当前输入法语言区域

    title author date CreateTime categories WPF 获得当前输入法语言区域 lindexi 2019-06-23 11:51:21 +0800 2018-10-12 ...

随机推荐

  1. Django框架的初使用

    1Django框架的初使用 说起Django框架,肯定需要首先明确一个概念,即软件框架.下面就是第一个问题: 1 软件框架(software framework) 1.1 概念界定 软件框架:通常指的 ...

  2. 机器学习-Tensorflow之Tensor和Dataset学习

    好了,咱们今天终于进入了现阶段机器学习领域内最流行的一个框架啦——TensorFlow.对的,这款由谷歌开发的机器学习框架非常的简单易用并且得到了几乎所有主流的认可,谷歌为了推广它的这个框架甚至单独开 ...

  3. 19_07_08校内训练[grid]

    题意 现有n*m的长方形网格,每个格子中写着一个数,并构成了[0,n*m)的排列.每次可以将一行循环平移x格,也可以将一列循环平移x格.给出初始状态,给出一个到达给定状态的方案.n*m<=100 ...

  4. ES6笔记分享 part 1

    ECMAScript ES6 从一脸懵逼到灵活运用 var let const var let const 的比较 声明与赋值 var声明的变量是可以重新赋值的,也可以重复声明 let和const声明 ...

  5. js----UTC时间于本地时间相差8小时问题

    js----UTC时间于本地时间相差8小时问题 js获取周几有两个方法getDay() getUTCDay(),但是它们是有区别的,前者返回的本地时间,后者返回的UTC时间,一般情况下,两者相差8个小 ...

  6. 理解RabbitMQ中的AMQP-0-9-1模型

    前提 之前有个打算在学习RabbitMQ之前,把AMQP详细阅读一次,挑出里面的重点内容.后来找了下RabbitMQ的官方文档,发现了有一篇文档专门介绍了RabbitMQ中实现的AMQP模型部分,于是 ...

  7. mac如何用quick look预览多个文件或者图片

    1.先选中要查看的多个文件,然后点击 空格键 2.按住 command+return 就可以同时预览多个文件了 如果想全屏预览,则在1中,按住 option+空格键 ,然后再进行2 ,就实现全屏预览了 ...

  8. 链表基本操作与排序(c语言)

    本设计程序用C编写,完成单链表的生成,任意位置的插入.删除,以及确定某一元素在单链表中的位置.实现三种排序算法-冒泡排序.快速排序.合并排序.产生四个长度为100,1000,10000,50000的随 ...

  9. Codeforces_101498

    A.map统计数量,更新最大值. #include<bits/stdc++.h> using namespace std; int n; map<int,int> mp; in ...

  10. constrainlayout布局

    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/r ...