下一个示例页面具有一个语言选择器、一个显示当前语言的标签和一个重新加载页面的按钮。
语言选择器绑定到一个带有setter的变量,在这里我可以更新我能想到的所有区域性设置。
标签成功地反映了选择器上的任何更改。但当我们点击按钮重新加载页面时,它不会记住更改。
@page "/test"
@inject NavigationManager NavigationManager
@using System.Globalization
<div class="Wrapper">
<select @bind="@Culture">
@foreach (var culture in cultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
<div>
Current culture: @CultureInfo.CurrentCulture.Name
</div>
<button @onclick="Reload">Reload the page</button>
</div>
<style>
.Wrapper {
display:flex;
flex-direction:column;
gap:15px;
max-width:200px;
margin:50px auto;
}
</style>
@code {
CultureInfo[] cultures = new[] {
new CultureInfo("es-ES"),
new CultureInfo("ca"),
new CultureInfo("en-US"),
new CultureInfo("pt-PT")
};
CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
Thread.CurrentThread.CurrentCulture = value;
Thread.CurrentThread.CurrentUICulture = value;
CultureInfo.DefaultThreadCurrentCulture = value;
CultureInfo.DefaultThreadCurrentUICulture = value;
}
}
}
void Reload() {
NavigationManager.NavigateTo(NavigationManager.Uri, true);
}
}
在@Liyun Zhang的帮助下,经过多次尝试和错误,我成功地用首选项存储取代了cookie存储,以保持所选的区域性:
- 创建一个新的.Net Maui Blazor应用程序项目并将其命名为"测试">
- 打开Nuget控制台并键入:
安装包Microsoft.Extensions.Localization
- 在CreateMauiApp((过程内的MauiProgram.cs中;返回生成器。Build(("行,插入下一行以注册本地化服务:
builder.Services.AddLocalization();
- 在这一行之后,插入下一行以将初始区域性设置为持久值或默认值(在这种情况下为西班牙语(:
string? cc = Preferences.Get("blazorCulture", null);
if (string.IsNullOrEmpty(cc)) {
cc = "es-ES";
Preferences.Default.Set("blazorCulture", cc);
}
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(cc);
- 将下一行附加到_Imports.razor,这样您就不必在每个文件上添加它们:
@using System.Globalization
@using Microsoft.Extensions.Localization
@using Test.Resources.Languages
在"资源"文件夹下,添加一个"语言"文件夹
在Languages文件夹下,添加一个资源文件并将其称为"MyStrings.resx">
打开MyStrings.resx并输入"HelloWorld"作为密钥;你好,世界"作为其默认值
添加一个名为"的新资源文件;MyStrings.es es.resx";欧洲-西班牙价值观
打开MyStrings.es-es.resx并输入"HelloWorld"作为密钥;你好,蒙多"作为其西班牙价值
添加一个名为"的新资源文件;MyStrings.ca.resx">
打开MyStrings.es-es.resx并输入"HelloWorld"作为密钥;你好,周一"作为其加泰罗尼亚价值
添加一个名为"的新资源文件;MyStrings.pt pt.resx";葡萄牙语和欧洲语言
打开MyStrings.pt-pt.resx并输入"HelloWorld"作为密钥;OláMundo"作为其葡萄牙价值。在Shared文件夹下,添加下一个Lang.razor组件,该组件允许您在可用语言列表中进行选择,并在选择更改时向组件主机发送回调通知。
<select @bind="@Culture">
@foreach (var culture in cultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
@code {
[Parameter] public EventCallback<CultureInfo> AfterUpdate { get; set; }
[Parameter]
public CultureInfo? Culture
{
get => _culture;
set
{
if (_culture != value)
{
_culture = value;
if (AfterUpdate.HasDelegate) AfterUpdate.InvokeAsync(value);
}
}
}
private CultureInfo? _culture;
CultureInfo[] cultures = new[] {
new CultureInfo("es-ES"),
new CultureInfo("ca"),
new CultureInfo("en-US"),
new CultureInfo("pt-PT")
};
}
- 为了使用该组件,请用以下代码替换Pages/Index.razor代码。AfterLangUpdate回调委托负责a(保持所选语言,在Preferences上设置新值,b(设置CurrentUICulture,以便Localizer可以选择正确的资源文件来显示翻译,c(重新加载页面,以确保新语言在任何地方都是活动的:
@page "/"
@inject IStringLocalizer<MyStrings> Localizer
@inject NavigationManager NavigationManager
<h1>@Localizer["HelloWorld"]</h1>
<Lang Culture="CultureInfo.DefaultThreadCurrentUICulture" AfterUpdate="AfterLangUpdate"></Lang>
@code {
private void AfterLangUpdate(CultureInfo culture) {
Preferences.Set("blazorCulture", culture.Name);
CultureInfo.DefaultThreadCurrentUICulture = culture;
NavigationManager.NavigateTo(NavigationManager.Uri, true);
}
}
原因是您没有将CultureInfo保存到Cookie中,而只是在页面中设置它。因此,当您更改页面或重新加载此页面时,CultureInfo将被刷新。你可以检查这个有同样问题的案例。
有关更多信息,您可以查看官方文件。
更新
更改maiprogram.cs:
public static class MauiProgram
{
public static async Task<MauiApp> CreateMauiAppAsync()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
builder.Services.AddMauiBlazorWebView();
#if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools();
#endif
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddLocalization();
var host = builder.Build();
CultureInfo culture;
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
if (result != null)
{
culture = new CultureInfo(result);
}
else
{
culture = new CultureInfo("en-US");
await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}
CultureInfo.DefaultThreadCurrentUICulture = culture;
return host;
}
}
并在每个平台中更改以下代码:
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiAppAsync().Result;