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 = https://www.cnblogs.com/weihanli/p/localizer[Key];
return (string)value;
}
}
這里使用到了上面提到的 ServiceLocator 模式的代碼,從 DependencyResolver 獲取注冊的服務,感覺這里的實作需要優化,有更好想法的小伙伴還望一起交流一下,另外如果你的應用比較簡單,我覺得上面代碼里的通過反射獲取 targetRootType 的代碼可以直接使用某一個型別例如:typeof(MainWindow) ,這樣會更高效
在 xaml 中使用
- 在
Window標簽中添加擴展對應的命令空間,例如:xmlns:loc="clr-namespace:DbTool.Localization" - 在需要實作多語言的地方參考,例如:
<TextBlock Margin="0,0,4,0" Text="{loc:Localizer DbConnectionString}"></TextBlock> - 在對應的資源檔案中配置要使用多語言資源,如上面的
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
- 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/59625.html
標籤:.NET Core
上一篇:.NET Core 3 Web Api Cors fetch 一直 307 Temporary Redirect
