WinUI 3 sepenuhnya mendukung fitur internasionalisasi. Meski secara teknis bahasa antarmuka dapat diperbarui secara dinamis tanpa memulai ulang aplikasi, cara paling andal saat ini adalah me-restart aplikasi setelah mengganti bahasa agar tampilan berfungsi dengan benar. Saya telah menghabiskan banyak waktu untuk memperbaiki berbagai masalah, seperti teks yang rusak atau aplikasi yang berhenti tiba-tiba saat peralihan bahasa. Setelah berbagai pengujian dan perbaikan, saya berhasil membuat alur kerja internasionalisasi yang stabil untuk WinUI 3, penjelasannya ada di bawah.
Pertama, tambahkan logika inisialisasi bahasa pada kode di belakang berkas App.xaml.cs. Jika pengguna tidak memilih bahasa kustom, aplikasi akan menggunakan bahasa bawaan sistem operasi. Apabila bahasa sistem tidak terdaftar dalam daftar bahasa yang didukung, aplikasi akan beralih ke bahasa Inggris.
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
const string LangSettingKey = "AppLanguageCode";
// All supported language tags of project
List<string> supportLangs = new() { "zh-CN", "en-US", "th-TH" };
string finalLang = "en-US"; // Default language
try
{
var localSetting = ApplicationData.Current.LocalSettings;
// ① Use saved language if local configuration exists
if (localSetting.Values.TryGetValue(LangSettingKey, out var savedVal))
{
finalLang = NormalizeLang(savedVal?.ToString() ?? "");
}
else
{
// ② No saved config: read system primary preferred language
string sysLang = ApplicationLanguages.Languages.FirstOrDefault() ?? "";
sysLang = NormalizeLang(sysLang);
// ③ Use system language if supported, otherwise fall back to English
finalLang = supportLangs.Contains(sysLang) ? sysLang : "en-US";
}
}
catch
{
// Ignore exception when running unpackaged, ApplicationData unavailable
}
ApplicationLanguages.PrimaryLanguageOverride = finalLang;
_window = new MainWindow();
_window.Activate();
}
/// <summary>
/// Standardize culture code: map system returned zh-Hans-CN to zh-CN
/// </summary>
private static string NormalizeLang(string lang)
{
if (string.IsNullOrEmpty(lang)) return lang;
return lang switch
{
"zh-Hans-CN" => "zh-CN",
"zh-Hant-TW" => "zh-TW", // For future Traditional Chinese support
_ => lang
};
}Code language: PHP (php)
Konfigurasi ini masih bisa dioptimalkan. Agar kode tetap rapi, jangan menuliskan daftar bahasa yang didukung secara langsung di sini. Pindahkan daftar tersebut ke kelas pembantu statis, sehingga Anda dapat menggunakannya kembali di seluruh bagian yang mengelola pengaturan bahasa.
public class Languages
{
public static List<string> supportLangs = new() { "zh-CN", "en-US", "th-TH" };
}Code language: PHP (php)
Fungsi utama blok kode di atas adalah mengatur bahasa saat aplikasi dijalankan: pertama muat preferensi bahasa yang disimpan pengguna, gunakan bahasa sistem jika tidak ada pengaturan kustom, dan jadikan bahasa Inggris sebagai cadangan terakhir.
Membuat halaman khusus untuk mengganti bahasa
Kami membutuhkan antarmuka khusus agar pengguna dapat mengubah bahasa tampilan, sehingga saya membuat halaman mandiri yang hanya berisi pengaturan bahasa.
<?xml version="1.0" encoding="utf-8"?>
<Page
x:Class="ThaiTong.Pages.LanguageSettingPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ThaiTong.Pages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<StackPanel Padding="20" Spacing="24">
<TextBlock x:Uid="Txt_LangTip" FontSize="22"/>
<ComboBox x:Name="cbLangSelect" Width="320" Height="40" CornerRadius="6">
<ComboBoxItem Tag="zh-CN" Content="简体中文"/>
<ComboBoxItem Tag="en-US" Content="English"/>
<ComboBoxItem Tag="th-TH" Content="ภาษาไทย"/>
</ComboBox>
<StackPanel Orientation="Horizontal" Spacing="12">
<Button x:Name="btnSave" x:Uid="Btn_Save" Content="Save" Click="BtnSave_Click" Width="120" Height="38" CornerRadius="5"/>
</StackPanel>
<TextBlock Foreground="Gray" Text="Note: After saving, page will refresh to apply language."/>
</StackPanel>
</Page>
Code language: HTML, XML (xml)
Berikut adalah kode C# bagian belakang yang sesuai:
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.Windows.ApplicationModel.Resources;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using ThaiTong.Common;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Globalization;
using Windows.Storage;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace ThaiTong.Pages
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class LanguageSettingPage : Page
{
private const string LangSettingKey = "AppLanguageCode";
private string _currentLang;
private readonly ResourceLoader _resLoader;
public LanguageSettingPage()
{
InitializeComponent();
_resLoader = new ResourceLoader();
var setting = ApplicationData.Current.LocalSettings;
if (setting.Values.TryGetValue(LangSettingKey, out var saveLang))
{
_currentLang = saveLang.ToString();
}
else
{
string sysLang = ApplicationLanguages.Languages.FirstOrDefault() ?? "";
_currentLang = Languages.supportLangs.Contains(sysLang) ? sysLang : "en-US";
}
// Pre-select matched language in dropdown list
foreach (var item in cbLangSelect.Items)
{
if (item is ComboBoxItem cbi && cbi.Tag.ToString() == _currentLang)
{
cbLangSelect.SelectedItem = item;
break;
}
}
}
// Save selected language setting
private async void BtnSave_Click(object sender, RoutedEventArgs e)
{
if (cbLangSelect.SelectedItem is not ComboBoxItem selectItem) return;
string newLang = selectItem.Tag.ToString();
if (_currentLang == newLang) return;
ApplicationData.Current.LocalSettings.Values[LangSettingKey] = newLang;
_currentLang = newLang;
ApplicationLanguages.PrimaryLanguageOverride = newLang;
// Load localized text from resw resource file
ContentDialog tipDialog = new ContentDialog()
{
XamlRoot = this.XamlRoot,
Title = _resLoader.GetString("Dlg_LangChange_Title"),
Content = _resLoader.GetString("Dlg_LangChange_Content"),
CloseButtonText = _resLoader.GetString("Dlg_LangChange_BtnOk")
};
await tipDialog.ShowAsync();
}
}
}
Code language: HTML, XML (xml)
Setiap kali pengguna menyimpan pengaturan bahasa baru, kami menyarankan untuk memulai ulang aplikasi agar seluruh teks antarmuka dapat diperbarui sepenuhnya.
Implementasi pelokalan pada WinUI 3 terbagi menjadi dua bagian terpisah: penanda dalam berkas XAML dan pembacaan teks pada kode C# bagian belakang.
Untuk elemen XAML, gunakan atribut x:Uid seperti contoh berikut:
<TextBlock x:Uid="Txt_LangTip" FontSize="22"/>Code language: HTML, XML (xml)
Selanjutnya, atur struktur folder sumber daya pelokalan: buat folder utama bernama Strings di dalam proyek, lalu tambahkan subfolder sesuai kode budaya, contohnya en-US untuk bahasa Inggris Amerika. Di setiap folder bahasa, buat berkas Resources.resw yang berisi pasangan kunci dan nilai untuk terjemahan.
<data name="Btn_Save.Content" xml:space="preserve">
<value>Simpan</value>
</data>Code language: HTML, XML (xml)
Bidang name berfungsi sebagai kunci pencarian. Akhiran .Content menunjuk ke properti elemen kontrol yang dituju. Elemen Txt_LangTip yang disebutkan sebelumnya didefinisikan sebagai berikut:
<data name="Txt_LangTip.Text" xml:space="preserve"><value>Pilih bahasa aplikasi</value></data>Code language: HTML, XML (xml)
Kami menambahkan .Text di sini karena mengarah secara khusus ke properti Text pada kontrol TextBlock.
Untuk teks dinamis di dalam kode C#, inisialisasikan terlebih dahulu instansi dari ResourceLoader:
private readonly ResourceLoader _resLoader;
public LanguageSettingPage()
{
InitializeComponent();
_resLoader = new ResourceLoader();Code language: PHP (php)
Setelah inisialisasi selesai, Anda dapat mengambil string yang telah dilokalkan di bagian mana pun dalam kode menggunakan metode GetString:
Title = _resLoader.GetString("Dlg_LangChange_Title"),Code language: JavaScript (javascript)