XAML WinUI 3运行时本地化

yiytaume  于 2022-12-07  发布在  其他
关注(0)|答案(4)|浏览(204)

我正在开发WinUI 3应用程序,目前陷入了本地化。虽然我为不同的文化编写了单独的resw资源文件,并使用x:Uid进行了本地化,但我找不到在应用程序运行时更改语言的方法。
设置Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride仅适用于设置启动语言。
WinUI 3中的运行时本地化甚至是可能的吗?

slsn1g29

slsn1g291#

我在这个问题上花了很多时间,以下是我真诚的建议:* * 不要尝试本地化您的视图**。另外,不要尝试在运行时处理语言的更改。没有人这样做,您永远不会看到投资的投资回报。
在视图模型中进行所有本地化,并使用内置在. NET DI中的StringLocalizer类。

this.serviceProvider = new ServiceCollection()
            .AddLogging()
            .AddLocalization();

然后,在. NET或. Net标准库的视图模型中,添加以下初始化:

private readonly IStringLocalizer<LandingViewModel> stringLocalizer;

public MyViewModel(IStringLocalizer<MyViewModel> stringLocalizer)
{
    this.stringLocalizer = stringLocalizer;
}

现在,如果您想要显示一些文本,比如说在按钮上,您可以:

public string SignUpText => this.stringLocalizer["SignUp"];

在XAML中,您将拥有:

<Button Content="{x:Bind ViewModel.SignUpText}"/>

最后,为RESX文件指定与视图模型相同的名称。它应该是一个嵌入式资源,没有自定义工具,这一点很重要:

7ivaypg9

7ivaypg92#

    • 原始答案:**

我认为你的思路是对的。如果你试图在运行时改变语言,调用一个方法,将Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride设置为新的语言"string"。但在那之后,你还必须修改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));

}
  • 或者-
    对于需要/想要刷新的UI组件,您必须调用ResourceLoader,一次只能刷新一个。
private void RefreshUIText()
{
    var resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();
    this.myXAMLTextBlockElement.Text = resourceLoader.GetString("Farewell");
}
    • 更新的答案:**

根据微软的在线文档,他们建议任何时候你为你改变语言"从默认的ResourceContext重新加载你的字符串"。我知道这并不理想,但它似乎起作用了。
我得到了下面的示例解决方案:

主窗口. xaml

<Grid>
    <Frame x:Name="MainFrame"/>
</Grid>

主窗口. xaml. cs

public MainWindow()
{
    this.InitializeComponent();
    MainFrame.Navigate(typeof(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>

主页面. 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");
    }
}

语言页面. 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>

语言页面. 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文件中添加语言声明

mepcadol

mepcadol3#

我创建了新项目-空白应用程序,与WAP打包(桌面中的WinUI 3)与最新的项目模板,它带有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)'

zsbz8rwp

zsbz8rwp4#

我有一个NuGet软件包,可以帮助您进行本地化。
https://github.com/AndrewKeepCoding/AK.Toolkit#-localizer

  • 无需重启应用程序
  • 允许您(用户)在部署后编辑本地化字符串
  • 让您(用户)即使在部署后也可以添加新语言
  • 使用标准的“资源.resw”

相关问题