WPFLocalizeExtension

repository·master·Indexed 20 days ago

https://github.com/xamlmarkupextensions/wpflocalizeextension

A library providing markup extensions and tools to localize DependencyProperties and native Properties on DependencyObjects in WPF applications. It supports .NET Framework 4.0+ and .NET CORE 3.0+, offering features such as automatic key lookup, custom localization providers (including RESX and CSV), runtime language swapping, and design-time support for Visual Studio and Expression Blend.

Tokens
8.1K
Snippets
20
Records
48
Agent score
72%

What's inside WPFLocalizeExtension

  1. Design-Time Support and Visual Testing

    master

    The extension is designed to work within visual designers like MS Visual Studio and MS Expression Blend without requiring a separate preview application.

    • Design-Time Availability: Works for standard assemblies at design time. (Note: Dynamic loaded assemblies that are only found at runtime may not be available unless the .resx is built at design time).
    • DesignValue Property: Use the DesignValue property to provide custom values to be displayed during design mode.
    • Visual Testing: You can define a specific design language to facilitate visual testing of your UI layouts in the designer.
  2. How the automatic key strategy works

    master

    The {lex:Loc} extension implements a "Don't Repeat Yourself" (DRY) strategy. If you do not provide a Key, the extension automatically generates one based on the element's x:Name and the target property being set.

    Example:

    <Button x:Name="MyButton" Content="{lex:Loc}" ToolTip="{lex:Loc}" FontSize="{lex:Loc}"/>

    In this case, the extension searches the default assembly and default resources for the following keys:

    • MyButton_Content (string)
    • MyButton_ToolTip (string)
    • MyButton_FontSize (double)

    If the resource type differs from the target property type, the extension attempts to convert it automatically. It uses TypeConverters and includes a built-in converter to map Bitmap resources to WPF BitmapSource types.

    <Button x:Name="MyButton" Content="{lex:Loc}" />
    <!-- Searches for key: MyButton_Content -->
  3. Configure Localization Providers in LocalizeDictionary

    master

    You can control where the extension looks for localized strings by configuring providers. This allows you to switch localization sources at different levels of your application's visual tree.

    • Global Configuration: Use the DefaultProvider property on LocalizeDictionary to set the provider for the entire application.
    • Sub-tree Configuration: Use the Provider property on a LocalizeDictionary instance at an arbitrary node to change the provider for that specific sub-tree.
    • Built-in Provider: The default provider is the RESX provider, which performs standard resource file lookups and is fully backward compatible.
    • Custom Providers: You can implement your own provider by using the provided interface. An example implementation using CSV is available in the project's Tests folder.
  4. Supported target types for LocExtension

    master

    The LocExtension automatically determines the target property's type and attempts to find an appropriate TypeConverter.

    • Standard Types: Most types are supported via standard WPF TypeConverter logic.
    • Bitmaps: The extension includes a built-in converter to transform Bitmap (from resource files) into BitmapSource (WPF).
    • Enums: Enum types are supported natively and do not require specific converters.
    • Custom Conversions: If you encounter an unsupported type, you can provide a custom IValueConverter by passing it as the Converter property and providing a ConverterParameter within the LocExtension declaration.
  5. The concept of localization in WPFLocalizeExtension

    master

    Localization involves adapting values like strings, colors, or text flow direction to a user's specific language and culture.

    To implement localization using this project, two prerequisites must be met:

    1. Marking the target: You must identify where a localized value should be applied in your XAML. This requires using the extension's tools to mark a specific spot and refer to a key in a translation dictionary.
    2. Providing translations: A cross-table must be maintained containing all the keys used in the XAML and their corresponding values for every supported culture.

    WPFLocalizeExtension simplifies the developer workflow by allowing you to define which values need localization directly in XAML during design time. The extension can even attempt to automatically find the correct key if one is not explicitly provided, which speeds up development while maintaining code readability.

  6. Extend localization with custom providers

    master

    You can extend the library's localization capabilities by plugging in a custom localization provider. To do this, implement the ILocalizationProvider interface.

    By default, the extension uses a provider that supports .resx files, which can be distributed across multiple assemblies in your project. You can replace this default provider with your own implementation (for example, a provider for CSV files) by configuring the localization providers settings.

  7. Use automatic key retrieval for localization

    master

    If you omit the key in the {lex:Loc} extension, the extension attempts to automatically resolve a key based on the control's Name or x:Name property. It searches for matching resource keys using the following priority order:

    1. ControlName_PropertyName (e.g., MyButton_Content for a Button's Content property).
    2. ControlName (e.g., MyButton).

    If neither pattern matches a key in your localization resources, no value will be provided.

    <!-- If Name is 'MyButton', it looks for 'MyButton_Content' then 'MyButton' -->
    <Button Name="MyButton" Content="{lex:Loc}" />
  8. Switching assemblies and dictionaries in the VisualTree

    master
    The ResxLocalizationProvider allows you to change the context of localization by updating ResxLocalizationProvider.DefaultAssembly and ResxLocalizationProvider.DefaultDictionary. You can set these values at arbitrary locations within your XAML VisualTree. All LocExtension instances will automatically resolve their keys based on the nearest defined assembly and dictionary in the tree. These values can also be changed dynamically during runtime.
  9. How localization providers work

    master

    The library separates target identification and value conversion (handled by LocExtension) from the actual value retrieval logic via the ILocalizationProvider interface. This decoupling allows you to swap out how localized values are fetched (e.g., from .resx files, CSVs, or custom services) without modifying the core markup extension logic.

    Providers provide three main capabilities:

    1. Value Lookup: Retrieving a localized object based on a key, target, and culture.
    2. Culture Discovery: Exposing an AvailableCultures observable collection that can be bound to UI elements (like language switchers).
    3. Change Notification: Firing events when critical values change (triggering UI updates via LocExtension) or when errors occur.
    public interface ILocalizationProvider
    {
        /// <summary>
        /// Get the localized object.
        /// </summary>
        /// <param name="key">The key to the value.</param>
        /// <param name="target">The target <see cref="DependencyObject"/>.</param>
        /// <param name="culture">The culture to use.</param>
        /// <returns>The value corresponding to the key and culture.</returns>
        object GetLocalizedObject(string key, DependencyObject target, CultureInfo culture);
    
        /// <summary>
        /// An observable list of available cultures.
        /// </summary>
        ObservableCollection<CultureInfo> AvailableCultures { get; }
    
        /// <summary>
        /// An event when the provider changed.
        /// </summary>
        event ProviderChangedEventHandler ProviderChanged;
    
        /// <summary>
        /// An event when an error occurred.
        /// </summary>
        event ProviderErrorEventHandler ProviderError;
    }
  10. Specify localization keys in XAML

    master

    You can provide the localization key to the lex:Loc extension in two ways:

    1. Directly after the extension name: Use the syntax {lex:Loc KeyName}.
    2. Using the Key property: Use the syntax {lex:Loc Key=KeyName}.

    Both methods are functionally identical.

    <!-- Method 1: Direct -->
    <Button Content="{lex:Loc Test}" />
    
    <!-- Method 2: Key property -->
    <Button Content="{lex:Loc Key=Test}" />
  11. How to get a treeview of culture-specific resources in the Solution Explorer

    master

    By default, culture-specific .resx files may appear as separate items in the Solution Explorer. To group them under the main resource file in a treeview structure, you must manually edit your .csproj file using the DependentUpon syntax.

    1. Unload the project.
    2. Edit the .csproj file.
    3. Locate the <EmbeddedResource> tags and ensure the culture-specific files use <DependentUpon> pointing to the main resource file, while the main file uses the ResXFileCodeGenerator.
        <EmbeddedResource Include="Strings.de.resx">
          <SubType>Designer</SubType>
          <DependentUpon>Strings.resx</DependentUpon>
        </EmbeddedResource>
        <EmbeddedResource Include="Strings.resx">
          <Generator>ResXFileCodeGenerator</Generator>
          <LastGenOutput>Strings.Designer.cs</LastGenOutput>
        </EmbeddedResource>