WinUI3 has surprisingly few documentation, and I can't even find how to switch the display language when the app is running
Back to the question, I created multiple languages' resource files, but I don't know how to let users choose the language they want to display.
In MainWindow.xaml
<ComboBox x:Name="LanguangeMode" SelectionChanged="Language_SelectionChanged">
<ComboBoxItem Content="English"/>
<ComboBoxItem Content="Simplified Chinese"/>
</ComboBox>
And in MainWindow.xaml.cs
private void Language_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var comboBox = sender as ComboBox;
var selectedIndex = comboBox.SelectedIndex;
switch (selectedIndex)
{
case 0:
// Change language to English
break;
case 1:
// Change language to Simplified Chinese
break;
}
}
This is a minimal example that demonstrates localization. (I also have a sample app repo and its video.)
x:Uid
to target controls in XAML or the GetString
method from ResourceLoader
for localization in C# code.MainWindow.xaml
<Window
x:Class="SwitchingLanguageExample.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:local="using:SwitchingLanguageExample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid RowDefinitions="Auto,Auto">
<ComboBox
Grid.Row="0"
ItemsSource="{x:Bind LanguageItems, Mode=OneWay}"
Loaded="ComboBox_Loaded"
SelectionChanged="ComboBox_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="local:LanguageItem">
<TextBlock Text="{x:Bind DisplayName}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!-- You need to set the x:Uid to target a control. -->
<Button
x:Uid="LocalizedButton"
Grid.Row="1" />
</Grid>
</Window>
MainWindow.cs.xaml
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.Windows.ApplicationModel.Resources;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.Globalization;
namespace SwitchingLanguageExample;
public class LanguageItem
{
public LanguageItem(string languageTag, string displayName)
{
LanguageTag = languageTag;
DisplayName = displayName;
}
public string LanguageTag { get; }
public string DisplayName { get; }
}
public sealed partial class MainWindow : Window
{
private ResourceManager resourceManager = new();
private ResourceLoader resourceLoader = new();
public MainWindow()
{
this.InitializeComponent();
LanguageItems.Add(new LanguageItem("en-US", this.resourceLoader.GetString("en-US")));
LanguageItems.Add(new LanguageItem("es-ES", this.resourceLoader.GetString("es-ES")));
}
public ObservableCollection<LanguageItem> LanguageItems { get; } = new();
private void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
if (sender is not ComboBox languageTagComboBox)
{
return;
}
if (LanguageItems
.Where(x => x.LanguageTag == ApplicationLanguages.PrimaryLanguageOverride)
.FirstOrDefault() is LanguageItem currentLanguageItem)
{
languageTagComboBox.SelectedValue = currentLanguageItem;
}
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is not ComboBox languageTagComboBox ||
languageTagComboBox.SelectedValue is not LanguageItem selectedLanguageItem)
{
return;
}
ApplicationLanguages.PrimaryLanguageOverride = selectedLanguageItem.LanguageTag;
ResourceContext resourceContext = this.resourceManager.CreateResourceContext();
resourceContext.QualifierValues["Language"] = selectedLanguageItem.LanguageTag;
}
}
NOTE
Unfortunately, you need to restart the app to see the change of languages. Also, this doesn't work on unpackaged (non-packaged) apps.
That's why I created the WinUI3Localizer. Give it a try. Hope it helps!