Antelcat.I18N

repository·main·Indexed 41 days ago

https://github.com/antelcat/i18n

A responsive multi-language support library for .NET applications targeting WPF (4.0+) and Avalonia (11.0+). It enables automatic UI updates upon culture changes via the I18NExtension.Culture property and supports both static .resx-based keys using the ResourceKeysOfAttribute and dynamic text bindings for external sources.

Tokens
2K
Snippets
8
Records
9
Agent score
50%

What's inside Antelcat.I18N

  1. Overview of Antelcat.I18N

    main

    Antelcat.I18N provides reactive language support for .NET applications, enabling automatic UI updates when the application culture changes. It is designed for modern .NET UI frameworks and supports automatic resource key generation.

    Supported Platforms:

    • WPF: Requires WPF 4.0 or higher.
    • Avalonia: Requires Avalonia 11.0 or higher.

    Key Features:

    • Static Usage: Bind to .resx files using auto-generated resource keys.
    • Dynamic Usage: Bind to strings received from external sources (like JSON/APIs) via standard Binding.
    • Reactive Updates: UI elements update automatically when I18NExtension.Culture is changed or when the underlying data source changes.
  2. Combine multiple sources with I18N and LanguageBinding

    main

    You can create complex, formatted strings by combining a template from a .resx file with multiple arguments provided via LanguageBinding or standard Binding.

    • I18N.Key: The string template (from .resx) containing placeholders like {0}, {1}.
    • LanguageBinding: Provides a key to look up a translation for a specific argument.
    • Binding: Provides a raw string value from the DataContext for an argument.
    <TextBlock>
        <TextBlock.Text>
            <I18N Key="{x:Static myProject:LangKeys.Current_is}">
                <LanguageBinding Key="{x:Static myProject:LangKeys.Language}"/>
                <Binding Path="Language"/>
            </I18N>
        </TextBlock.Text>
    </TextBlock>
  3. Text Composition and Formatting

    main

    You can combine multiple text sources and apply formatting to a template string using the I18N and LanguageBinding markup extensions.

    In this pattern, the I18N.Key acts as a format string (e.g., "The {0} is {1}"). You then provide arguments for the placeholders using <LanguageBinding /> (for localized keys) and standard <Binding /> (for ViewModel properties). The arguments are applied to the template in the order they are defined, and the entire expression remains responsive to culture changes.

    <!-- 1. I18N.Key is the template: "The {0} is {1}" -->
    <TextBlock>
        <TextBlock.Text>
            <I18N Key="{x:Static myProject:LangKeys.Current_is}">
                <!-- Argument {0}: A localized key -->
                <LanguageBinding Key="{x:Static myProject:LangKeys.Language}"/>
                <!-- Argument {1}: A property from the ViewModel -->
                <Binding Path="Language"/> 
            </I18N>
        </TextBlock.Text>
    </TextBlock>
  4. Dynamic Usage for External Text

    main

    When your source text is not defined in .resx files (e.g., it comes from a network API or a database), you can bind directly to the text using the {I18N ...} markup extension.

    If the text in your ViewModel matches a key in your .resx translation files, the {I18N} extension will automatically look up the translation. The UI will update whenever either the ViewModel property changes or the application culture changes.

    <!-- If 'Message' is a property in your DataContext/ViewModel -->
    <TextBlock Text="{I18N {Binding Message}}"/>
  5. Generate resource keys with ResourceKeysOfAttribute

    main

    To avoid manual string management for .resx files, you can use the ResourceKeysOfAttribute to automatically generate a partial class containing your resource keys. This allows you to use x:Static in XAML to reference keys safely.

    1. Apply the [ResourceKeysOf] attribute to a partial class.
    2. Pass the type of your generated .resx designer class to the attribute.

    Note for Avalonia users: If using Avalonia version 2.0.0 or higher, you must initialize the keys in App.axaml using LangKeys.Your_Provider.Initialize();. WPF users can skip this step.

    using Antelcat.I18N.Attributes;
    
    namespace MyProject
    
    // The generated class must be partial
    [ResourceKeysOf(typeof(My.Resource.Designer.Type))]
    public partial class LangKeys;
  6. Static Usage with .resx files

    main

    If you use .resx files for your localization, you can use the ResourceKeysOfAttribute to automatically generate a class containing your resource keys. This allows you to reference keys in XAML using x:Static.

    1. Generate Resource Keys

    Apply the [ResourceKeysOf] attribute to a partial class, passing the type of your generated resource designer class.

    2. Platform Initialization

    • Avalonia: You must call .Initialize() on your generated keys class in App.axaml (e.g., LangKeys.Your_Provider.Initialize()).
    • WPF: Initialization is not required.

    3. Use in XAML

    Use x:Static to reference the key, and wrap it with the {I18N ...} markup extension to enable responsiveness.

    4. Change Language

    To switch languages, update the I18NExtension.Culture property with a new CultureInfo object.

    // 1. Generate Keys
    using Antelcat.I18N.Attributes;
    
    namespace MyProject
    {
        [ResourceKeysOf(typeof(My.Resource.Designer.Type))]
        public partial class LangKeys;
    }
    
    // 2. Avalonia Initialization (in App.axaml.cs)
    LangKeys.Your_Provider.Initialize();
    
    // 3. Change Language
    using System.Globalization;
    I18NExtension.Culture = new CultureInfo("en-US");
    <!-- XAML Usage -->
    <TextBlock Text="{x:Static myProject:LangKeys.Language}"/>
    <TextBlock Text="{I18N {x:Static myProject:LangKeys.Language}}"/>
  7. Dynamic usage: Bind to external string sources

    main

    You can use I18N to translate strings that are not defined in .resx files but are provided dynamically (e.g., from a JSON API). If the dynamic string matches a key in your .resx translation files, I18N will perform the lookup.

    Example Scenario:

    1. API returns: {"message": "This is a message"}
    2. .resx contains translation for key This is a message: <value>这是一条消息</value>
    3. ViewModel has a property Message containing the string.

    XAML Binding:

    <TextBlock Text="{I18N {Binding Message}}"/>

    The text will update automatically whenever the Message property changes or the application culture changes.

  8. Static usage: Bind to .resx resources in XAML

    main

    Once resource keys are generated, you can bind them to UI elements in XAML using the I18N markup extension combined with x:Static.

    If your .resx contains:

    <data name="Language" xml:space="preserve">
        <value>Language</value>
    </data>

    You can bind it in XAML like this:

    <TextBlock Text="{I18N {x:Static myProject:LangKeys.Language}}"/>
  9. Change application language at runtime

    main

    To trigger a reactive update across the entire application when the language changes, update the I18NExtension.Culture property with a new CultureInfo object.

    using System.Windows;
    using System.Globalization;
    
    I18NExtension.Culture = new CultureInfo("language code");