美文网首页.NETAmazing .NETdotNET
dotnetcore3.1 WPF 实现多语言

dotnetcore3.1 WPF 实现多语言

作者: 天天向上卡索 | 来源:发表于2020-02-26 22:54 被阅读0次

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 实现多语言

    dotnetcore3.1 WPF 实现多语言 Intro 最近把 DbTool 从 WinForm 迁移到了 W...

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

    dotnetcore3.1 WPF 中使用依赖注入 Intro 在 ASP.NET Core 中默认就已经集成了依...

  • Flutter 多语言&多主题实现

    目录 多语言实现 多主题实现 状态管理 切换多语言 切换多主题 多语言实现 1. AndroidStudio-> ...

  • WPF中使用传感器

    在WPF 中使用传感器已知有两种方式可以实现: C++通过实现COM接口的方式拿到数据,再传到WPF中使用 直接使...

  • WPF简介

    目录 什么是WPF? WPF的历史? 为什么要用WPF及WPF作用 WPF与winForm区别? 什么是WPF? ...

  • 关于用mfc(c++)调用wpf(C#)编写的dll,实现界面消

    关于用mfc(c++)调用wpf(C#)编写的dll,实现界面消息回调的方法。 这几天有一个小项目。使用wpf...

  • 【WPF】WPF介绍

    一、WPF简介 WPF:WPF即Windows Presentation Foundation,翻译为中文“Win...

  • iOS多语言构建技巧

    虽说是讲多语言,但是这里不讲怎么实现多语言,因为各大网站都有说,而且这个技术不在话下。 今天来讲讲构建多语言文件,...

  • iOS多语言构建技巧

    虽说是讲多语言,但是这里不讲怎么实现多语言,因为各大网站都有说,而且这个技术不在话下。 今天来讲讲构建多语言文件,...

  • WPF中使用加速键(或称访问键)

    在界面中有很多字母带下划线的加速键如下图中带下划线的字母,在WPF如何实现呢? 如何定义 WPF中定义比较简单,就...

网友评论

    本文标题:dotnetcore3.1 WPF 实现多语言

    本文链接:https://www.haomeiwen.com/subject/bgrmxhtx.html