少有人走的路

勇哥的工业自动化技术网站

Avalonia学习(十)多语言

多语言


image.png



LocalizationService.cs

using System.Collections.Generic;
using System.Globalization;

namespace _10_Localization.Services;

public class LocalizationService
{
    private static LocalizationService? _instance;
    public static LocalizationService Instance => _instance ??= new LocalizationService();

    private string _currentLanguage = "zh-CN";
    public string CurrentLanguage => _currentLanguage;

    public event System.Action? LanguageChanged;

    private readonly Dictionary<string, Dictionary<string, string>> _translations = new()
    {
        ["zh-CN"] = new Dictionary<string, string>
        {
            ["WelcomeText"] = "欢迎",
            ["WelcomeMessage"] = "欢迎使用多语言演示应用",
            ["UsernameLabel"] = "用户名",
            ["PasswordLabel"] = "密码",
            ["LoginButtonText"] = "登录",
            ["RegisterButtonText"] = "注册",
            ["LanguageLabel"] = "语言",
            ["SelectLanguageText"] = "选择语言",
            ["CurrentLanguageText"] = "当前语言:简体中文"
        },
        ["en-US"] = new Dictionary<string, string>
        {
            ["WelcomeText"] = "Welcome",
            ["WelcomeMessage"] = "Welcome to Localization Demo App",
            ["UsernameLabel"] = "Username",
            ["PasswordLabel"] = "Password",
            ["LoginButtonText"] = "Login",
            ["RegisterButtonText"] = "Register",
            ["LanguageLabel"] = "Language",
            ["SelectLanguageText"] = "Select Language",
            ["CurrentLanguageText"] = "Current Language: English"
        },
        ["ja-JP"] = new Dictionary<string, string>
        {
            ["WelcomeText"] = "ようこそ",
            ["WelcomeMessage"] = "多言語デモアプリへようこそ",
            ["UsernameLabel"] = "ユーザー名",
            ["PasswordLabel"] = "パスワード",
            ["LoginButtonText"] = "ログイン",
            ["RegisterButtonText"] = "登録",
            ["LanguageLabel"] = "言語",
            ["SelectLanguageText"] = "言語を選択",
            ["CurrentLanguageText"] = "現在の言語:日本語"
        }
    };

    public string[] AvailableLanguages => new[] { "zh-CN", "en-US", "ja-JP" };

    public string GetLanguageDisplayName(string code) => code switch
    {
        "zh-CN" => "简体中文",
        "en-US" => "English",
        "ja-JP" => "日本語",
        _ => code
    };

    public void SetLanguage(string languageCode)
    {
        if (_translations.ContainsKey(languageCode) && _currentLanguage != languageCode)
        {
            _currentLanguage = languageCode;
            LanguageChanged?.Invoke();
        }
    }

    public string this[string key]
    {
        get
        {
            if (_translations.TryGetValue(_currentLanguage, out var dict) && dict.TryGetValue(key, out var value))
                return value;
            return key;
        }
    }
}


MainWindowViewModel.cs

using _10_Localization.Services;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace _10_Localization.ViewModels;

public partial class MainWindowViewModel : ObservableObject
{
    private readonly LocalizationService _loc = LocalizationService.Instance;

    [ObservableProperty]
    private string _welcomeText;

    [ObservableProperty]
    private string _welcomeMessage;

    [ObservableProperty]
    private string _usernameLabel;

    [ObservableProperty]
    private string _passwordLabel;

    [ObservableProperty]
    private string _loginButtonText;

    [ObservableProperty]
    private string _registerButtonText;

    [ObservableProperty]
    private string _languageLabel;

    [ObservableProperty]
    private string _selectLanguageText;

    [ObservableProperty]
    private string _currentLanguageText;

    [ObservableProperty]
    private string _selectedLanguage;

    [ObservableProperty]
    private string _statusMessage = "";

    public string[] AvailableLanguages => _loc.AvailableLanguages;

    public MainWindowViewModel()
    {
        SelectedLanguage = _loc.CurrentLanguage;
        UpdateAllTexts();
        _loc.LanguageChanged += UpdateAllTexts;
    }

    partial void OnSelectedLanguageChanged(string value)
    {
        if (value == null) return;
        _loc.SetLanguage(value);
    }

    [RelayCommand]
    private void Login()
    {
        StatusMessage = $"{LoginButtonText} 成功";
    }

    [RelayCommand]
    private void Register()
    {
        StatusMessage = $"{RegisterButtonText} 成功";
    }

    private void UpdateAllTexts()
    {
        WelcomeText = _loc["WelcomeText"];
        WelcomeMessage = _loc["WelcomeMessage"];
        UsernameLabel = _loc["UsernameLabel"];
        PasswordLabel = _loc["PasswordLabel"];
        LoginButtonText = _loc["LoginButtonText"];
        RegisterButtonText = _loc["RegisterButtonText"];
        LanguageLabel = _loc["LanguageLabel"];
        SelectLanguageText = _loc["SelectLanguageText"];
        CurrentLanguageText = _loc["CurrentLanguageText"];
    }
}


App.axaml

<Application xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Class="_10_Localization.App">

  <!-- 主题 -->
  <Application.Styles>
    <FluentTheme />
  </Application.Styles>

  <!-- 多语言资源字典 -->
  <Application.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <!-- 在这里加载语言文件 -->
       
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </Application.Resources>

</Application>



MainWindow.axaml

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:_10_Localization.ViewModels"
        x:Class="_10_Localization.MainWindow"
         x:DataType="vm:MainWindowViewModel"
        Title="Localization - 多语言切换演示"
        Width="450"
        Height="500">
  <Window.DataContext>
    <vm:MainWindowViewModel/>
  </Window.DataContext>

  <ScrollViewer>
    <StackPanel Margin="30" Spacing="20">

      <TextBlock Text="{Binding WelcomeText}"
                 FontSize="24"
                 FontWeight="Bold"
                 HorizontalAlignment="Center"/>

      <Border Background="#E3F2FD" Padding="15" CornerRadius="8">
        <TextBlock Text="{Binding WelcomeMessage}"
                   TextWrapping="Wrap"
                   HorizontalAlignment="Center"/>
      </Border>

      <Border Background="#F5F5F5" Padding="15" CornerRadius="8">
        <StackPanel Spacing="15">
          <StackPanel Spacing="5">
            <TextBlock Text="{Binding UsernameLabel}"/>
            <TextBox Watermark="{Binding UsernameLabel}"/>
          </StackPanel>

          <StackPanel Spacing="5">
            <TextBlock Text="{Binding PasswordLabel}"/>
            <TextBox PasswordChar="*"
                     Watermark="{Binding PasswordLabel}"/>
          </StackPanel>

          <StackPanel Orientation="Horizontal" Spacing="10" HorizontalAlignment="Center">
            <Button Content="{Binding LoginButtonText}"
                    Command="{Binding LoginCommand}"
                    Padding="20,8"/>
            <Button Content="{Binding RegisterButtonText}"
                    Command="{Binding RegisterCommand}"
                    Padding="20,8"/>
          </StackPanel>
        </StackPanel>
      </Border>

      <Border Background="#FFF3E0" Padding="15" CornerRadius="8">
        <StackPanel Spacing="10">
          <TextBlock Text="{Binding LanguageLabel}"
                     FontSize="16"
                     FontWeight="Bold"/>
          <TextBlock Text="{Binding SelectLanguageText}"/>
          <ComboBox ItemsSource="{Binding AvailableLanguages}"
                    SelectedItem="{Binding SelectedLanguage}"
                    Width="200"
                    HorizontalAlignment="Left">
            <ComboBox.ItemTemplate>
              <DataTemplate>
                <TextBlock>
                  <TextBlock.Text>
                    <MultiBinding StringFormat="{}{0}">
                      <Binding Path="."/>
                    </MultiBinding>
                  </TextBlock.Text>
                </TextBlock>
              </DataTemplate>
            </ComboBox.ItemTemplate>
          </ComboBox>
          <TextBlock Text="{Binding CurrentLanguageText}"
                     Foreground="#6200EE"/>
        </StackPanel>
      </Border>

      <TextBlock Text="{Binding StatusMessage}"
                 FontSize="14"
                 Foreground="#4CAF50"
                 HorizontalAlignment="Center"/>

      <Border Background="#E8F5E9" Padding="15" CornerRadius="8">
        <StackPanel Spacing="10">
          <TextBlock Text="学习要点" FontWeight="Bold" Foreground="#1565C0"/>
          <TextBlock Text="- 使用 ResourceDictionary 定义多语言字符串"
                     TextWrapping="Wrap"/>
          <TextBlock Text="- 创建 LocalizationService 管理当前语言"
                     TextWrapping="Wrap"/>
          <TextBlock Text="- 语言切换后通过事件通知所有 UI 更新"
                     TextWrapping="Wrap"/>
          <TextBlock Text="- 可结合 ILSpy 或资源文件实现更完整方案"
                     TextWrapping="Wrap"/>
        </StackPanel>
      </Border>

    </StackPanel>
  </ScrollViewer>
</Window>


MainWindow.axaml.cs

using Avalonia.Controls;

namespace _10_Localization;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}




效果:

act9.gif


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

«    2026年3月    »
1
2345678
9101112131415
16171819202122
23242526272829
3031
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接

Powered By Z-BlogPHP 1.7.3

Copyright www.skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864