dotnetcore3.1 WPF 实现多语言

您所在的位置:网站首页 dbstool dotnetcore3.1 WPF 实现多语言

dotnetcore3.1 WPF 实现多语言

2023-08-26 19:48| 来源: 网络整理| 查看: 265

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 _localizer; public MainWindow( IStringLocalizer 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(); } 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 中使用 在 Window 标签中添加扩展对应的命令空间,例如: xmlns:loc="clr-namespace:DbTool.Localization" 在需要实现多语言的地方引用,例如: 在对应的资源文件中配置要使用多语言资源,如上面的 DbConnectionString 语言切换

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

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

中文

英文

More

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

Reference https://github.com/WeihanLi/WeihanLi.Extensions.Localization.Json https://github.com/WeihanLi/DbTool https://github.com/WeihanLi/DbTool/blob/wpf-dev/DbTool/MainWindow.xaml https://github.com/WeihanLi/DbTool/blob/wpf-dev/DbTool/MainWindow.xaml.cs https://github.com/WeihanLi/DbTool/blob/wpf-dev/DbTool/Localization/LocalizerExtension.cs


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3