WinUI 3, uluslararasılaştırma özelliğini tam olarak destekler. Teknik olarak arayüz dilini yeniden başlatmadan dinamik olarak güncellemek mümkün olsa da, mevcut en güvenilir yöntem dil değiştirildikten sonra uygulamayı yeniden başlatmaktır. Bu sayede arayüz sorunsuz görüntülenir. Uzun süre hata giderme çalışmaları yaptım ve dil değişimi sırasında metin bozulması veya uygulamanın çökmesi gibi sorunlarla sıkça karşılaştım. Birçok test ve düzeltme sonrası WinUI 3 için kararlı bir uluslararasılaştırma iş akışı oluşturdum, detayları aşağıda açıklanmaktadır.
Önce App.xaml.cs arka plan koduna dil başlatma mantığını ekleyin. Kullanıcı özel bir dil seçmezse uygulama, işletim sisteminin varsayılan dilini kullanır. Sistem dili desteklenen diller listesinde yoksa uygulama İngilizceye geçer.
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)
Bu yapılandırma daha da iyileştirilebilir. Kodun düzenli kalması için desteklenen diller listesini doğrudan buraya yazmayın. Listeyi statik bir yardımcı sınıfa taşıyın, böylece dil ayarlarının yönetildiği tüm alanlarda aynı listeyi yeniden kullanabilirsiniz.
public class Languages
{
public static List<string> supportLangs = new() { "zh-CN", "en-US", "th-TH" };
}Code language: PHP (php)
Yukarıdaki kod bloğunun temel görevi uygulama başladığında dili ayarlamaktır: öncelikle kullanıcının kaydettiği dil tercihini yükler, özel ayar yoksa sistem dilini kullanır ve son yedek seçenek olarak İngilizceyi alır.
Dil Değiştirme için Özel Sayfa Oluşturma
Kullanıcıların görüntüleme dilini değiştirebilmesi için özel bir arayüze ihtiyaç duyarız. Bu nedenle yalnızca dil ayarları için bağımsız bir sayfa oluşturdum.
<?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)
Karşılık gelen arka plan C# kodu aşağıdadır:
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)
Kullanıcı yeni bir dil ayarını kaydettiğinde, arayüzdeki tüm metinlerin tam olarak güncellenmesi için uygulamayı yeniden başlatmasını öneririz.
WinUI 3’te yerelleştirme uygulaması iki ayrı bölüme ayrılır: XAML dosyalarındaki işaretlemeler ve arka plandaki C# kodunda metin okuma işlemleri.
XAML öğeleri için örnekte olduğu gibi x:Uid özniteliğini kullanın:
<TextBlock x:Uid="Txt_LangTip" FontSize="22"/>Code language: HTML, XML (xml)
Ardından yerelleştirme kaynak klasör yapısını ayarlayın: Proje kök dizininde Strings adında bir klasör oluşturun ve kültür kodlarına göre alt klasörler ekleyin. Örneğin Amerika İngilizcesi için en-US klasörü kullanılır. Her dil klasörü içinde çeviriler için anahtar-değer çiftleri içeren Resources.resw dosyasını oluşturun.
<data name="Btn_Save.Content" xml:space="preserve">
<value>Kaydet</value>
</data>Code language: HTML, XML (xml)
Name alanı arama anahtarı olarak görev yapar. .Content soneki hedef denetimin özelliğini belirtir. Daha önce bahsedilen Txt_LangTip öğesi şu şekilde tanımlanır:
<data name="Txt_LangTip.Text" xml:space="preserve"><value>Uygulama dilini seçin</value></data>Code language: HTML, XML (xml)
Buraya .Text eklenmesinin nedeni, özellikle TextBlock denetiminin Text özelliğini hedeflemektir.
C# kodundaki dinamik metinler için öncelikle ResourceLoader örneğini başlatın:
private readonly ResourceLoader _resLoader;
public LanguageSettingPage()
{
InitializeComponent();
_resLoader = new ResourceLoader();Code language: PHP (php)
Başlatma işlemi tamamlandıktan sonra GetString metodunu kullanarak kodun her yerinde yerelleştirilmiş metinleri alabilirsiniz:
Title = _resLoader.GetString("Dlg_LangChange_Title"),Code language: JavaScript (javascript)