dotnetcore3.1 WPF 实现多语言

Intro

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

服务注册

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

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

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

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

  1. DependencyResolver.SetDependencyResolver(services);

代码文件实现方式

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

  1. public partial class MainWindow: Window
  2. {
  3. private readonly IStringLocalizer<MainWindow> _localizer;
  4. public MainWindow(
  5. IStringLocalizer<MainWindow> localizer)
  6. {
  7. InitializeComponent();
  8. _localizer = localizer;
  9. }
  10. // ...
  11. {
  12. // ...
  13. MessageBox.Show(_localizer["Success"], _localizer["Tip"]);
  14. }
  15. }

xaml 实现方式

LocaliazerExtension

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

  1. public class LocalizerExtension : MarkupExtension
  2. {
  3. private readonly IStringLocalizerFactory _localizerFactory;
  4. public string Key { get; }
  5. public LocalizerExtension(string key)
  6. {
  7. Key = key;
  8. _localizerFactory = DependencyResolver.Current.
  9. ResolveService<IStringLocalizerFactory>();
  10. }
  11. public override object ProvideValue(IServiceProvider serviceProvider)
  12. {
  13. var targetRootType = serviceProvider.GetType()
  14. .GetProperty("System.Xaml.IRootObjectProvider.RootObject", BindingFlags.Instance | BindingFlags.NonPublic)
  15. ?.GetValue(serviceProvider)
  16. ?.GetType();
  17. if (null == targetRootType)
  18. {
  19. targetRootType = typeof(MainWindow);
  20. }
  21. var localizer = _localizerFactory.Create(targetRootType);
  22. var value = localizer[Key];
  23. return (string)value;
  24. }
  25. }

这里使用到了上面提到的 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
  1. <Window x:Class="DbTool.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6. xmlns:loc="clr-namespace:DbTool.Localization"
  7. mc:Ignorable="d"
  8. Title="DbTool" Height="450" Width="800" FontSize="14">
  9. <Grid>
  10. <TextBlock Margin="0,0,4,0" Text="{loc:Localizer DbConnectionString}"></TextBlock>
  11. </Grid>
  12. </Window>

语言切换

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

  1. // set current culture
  2. var defaultCulture = "zh";
  3. Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(defaultCulture);
  4. 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. OGG bi-directional replication for Oracle DB

    Overview of an Active-Active Configuration Oracle GoldenGate supports an active-active bi-directiona ...

  2. 正斜杠(" / ")和反斜杠(" \ ")的区别

    反斜杠“\”是电脑出现了之后为了表示程序设计里的特殊含义才发明的专用标点.所以除了程序设计领域外,任何地方都不应该使用反斜杠. 如何区分正反斜杠 英语:"/" 英文是forward ...

  3. SpringBoot整合三大组建(Servlet、Listener、Filter)

    >[更多资源和教程请关注公众号:**非科班的科班**.如果觉得我写的还可以请给个赞,谢谢大家,你的鼓励是我创作的动力](https://blog.csdn.net/qq_43255017)## ...

  4. [ZJOI2006]书架(权值splay)

    [ZJOI2006]书架(luogu) Description 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看 ...

  5. [JSOI2008]最大数(并查集)

    并查集的神奇用法:[JSOI2008]最大数 Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出 ...

  6. CSS-17-页面布局

    页面布局: 静态布局: 静态布局:元素不变的布局. 布局特点:缩小后内容被遮挡,拖动滚动条显示布局 设计方法: PC:居中布局,所有样式使用绝对宽度和高度 移动设备:另外建立移动网站,以m.域名为域名 ...

  7. [C语言学习笔记一]基本构架和变量

    基本构架 所有的C程序都有一个 main 函数.其后包含在大括号中的是 main 函数的内容. main函数是程序的入口,程序运行后,先进入 main 函数,然后一次执行 main 函数体中的语句. ...

  8. 使用visual studio 2013读取.mat文件

    现在有一个T.mat 文件需要在c++中处理然后以.mat 或是.txt形式返回 T.mat中存储了十个cell,每个cell中会有一个不等长的数组 1.以下是相关配置过程: 参考:http://we ...

  9. java.net.UnknownHostException 异常处理(个人案例)

    案例 今天在公司开发中,遇到一个比较奇怪的异常 ,java.net.UnknownHostException 异常处理  ,一直没找到什么好的办法解决 解决方案 在公司的项目开发中,项目都是连了很多个 ...

  10. (数据科学学习手札74)基于geopandas的空间数据分析——数据结构篇

    本文对应代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 geopandas是建立在GEOS.GDAL.P ...