【发布时间】:2022-01-23 04:03:36
【问题描述】:
我正在开发 WinUI 3 应用程序,目前卡在本地化上。尽管我为不同的文化编写了单独的 resw 资源文件并使用 x:Uid 进行了本地化,但我找不到在应用运行时更改语言的方法。
设置Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride仅适用于设置启动语言。
WinUI 3 中的运行时本地化是否可能?
【问题讨论】:
我正在开发 WinUI 3 应用程序,目前卡在本地化上。尽管我为不同的文化编写了单独的 resw 资源文件并使用 x:Uid 进行了本地化,但我找不到在应用运行时更改语言的方法。
设置Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride仅适用于设置启动语言。
WinUI 3 中的运行时本地化是否可能?
【问题讨论】:
原答案:
我认为你在正确的轨道上。如果您尝试在运行时更改语言,请调用将Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride 设置为新语言“字符串”的方法。但在那之后,你还必须reload your Page so that the new language takes effect。
private void ReloadLanguage(string languageOverride)
{
// Change the app language
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = languageOverride;
// Be sure to clear the Frame stack so that cached Pages are removed, otherwise they will have the old language.
Frame.BackStack.Clear();
// Reload the page that you want to have the new language
Frame.Navigate(typeof(MainPage));
}
-或-
您必须call your ResourceLoader 获取您需要/想要一次刷新一个的 UI 组件。
private void RefreshUIText()
{
var resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();
this.myXAMLTextBlockElement.Text = resourceLoader.GetString("Farewell");
}
更新答案:
根据Microsoft online documentation,他们建议您随时更改语言以“从默认的ResourceContext 重新加载您的字符串”。我知道这并不理想,但它似乎有效。
我得到了以下示例解决方案:
MainWindow.xaml
<Grid>
<Frame x:Name="MainFrame"/>
</Grid>
MainWindow.xaml.cs
public MainWindow()
{
this.InitializeComponent();
MainFrame.Navigate(typeof(MainPage));
}
MainPage.xaml
<Grid>
<StackPanel>
<TextBlock x:Uid="Greeting" x:Name="Greeting" Text="" Margin="15"/>
<TextBlock x:Uid="Farewell" x:Name="Farewell" Text="" Margin="15"/>
<Button x:Name="SelectLanguageButton" Click="SelectLanguageButton_Click" Content="Select Language" Margin="15"/>
</StackPanel>
</Grid>
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.Loaded += MainPage_Loaded;
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
RefreshUIText();
}
private void SelectLanguageButton_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(LanguagePage));
}
private void RefreshUIText()
{
var resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForViewIndependentUse();
this.Greeting.Text = resourceLoader.GetString("Greeting/Text");
this.Farewell.Text = resourceLoader.GetString("Farewell/Text");
}
}
LanguagePage.xaml
<Grid>
<StackPanel>
<Button x:Name="EnglishButton" Click="EnglishButton_Click" Content="English" Margin="15"/>
<Button x:Name="FrenchButton" Click="FrenchButton_Click" Content="French" Margin="15"/>
</StackPanel>
</Grid>
LanguagePage.xaml.cs
public sealed partial class LanguagePage : Page
{
public LanguagePage()
{
this.InitializeComponent();
}
private void EnglishButton_Click(object sender, RoutedEventArgs e)
{
ReloadLanguage("en");
}
private void FrenchButton_Click(object sender, RoutedEventArgs e)
{
ReloadLanguage("fr");
}
private void ReloadLanguage(string languageOverride)
{
// Change the app language
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = languageOverride;
// Be sure to clear the Frame stack so that cached Pages are removed, otherwise they will have the old language.
Frame.BackStack.Clear();
// Reload the page that you want to have the new language
Frame.Navigate(typeof(MainPage));
}
}
资源文件和内容,解决方案资源管理器
还记得在 Package.appxmanifest 文件中添加您的语言声明
【讨论】:
我创建了新项目 - Blank App, Packaged with WAP(WinUI 3 in Desktop) 带有最新的项目模板,带有 VS 扩展 Windows APP SDK C# VS2019。正如您所注意到的 - 我正在使用 VS 2019,社区版。我在下面附上一个项目的 csproj 配置。
主窗口中有一个框架导航到主页。主页上只有一个按钮,点击后会跳转到 LanguagePage。
目标是更改语言、清除导航堆栈并导航回主页。然而,SetAppLanguage 中的各种场景并没有产生想要的结果。
请查看https://www.py4u.net/discuss/731870 - 尝试了所有场景,对 GUI 没有影响。
尽管如此,Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView(); 正在抛出 COMException:'资源上下文可能不会在没有 CoreWindow 的线程上创建。 (0x80073B27)'
【讨论】: