Динамическое локализованное приложение WPF с файлами ресурсов - PullRequest
0 голосов
/ 11 мая 2018

Пытаясь сделать приложение wpf локализованным, я следовал этому руководству CodeProject .

Я создал свои файлы локализованных ресурсов (например, Resource.resx, Resource.en-US.resx)и привязать их к элементу метки в xaml

<Label Foreground="{StaticResource ApplicationForgroundColor}" FontSize="21"
           Content="{x:Static strings:Resources.title}"/> 

В LocalizedService я устанавливаю CultureInfo для некоторых событий изменения

class LocalizationService
{
    public static void SetLanguage(string locale)
    {
        if (string.IsNullOrEmpty(locale)) locale = "en-US";
        System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(locale);
    }
}

Это решение компилирует и показывает правильное значение ресурса, но из-за статической привязки я не смог изменить локаль во время выполнения.Когда я изменяю привязку содержимого к DynamicResource, как показано ниже, значение ресурса не отображается.

Content="{DynamicResource strings:Resources.title}"

Как я могу привязать текстовые значения к локализованному файлу ресурса и динамически изменить его во время выполнения?

1 Ответ

0 голосов
/ 11 мая 2018

Существует другой подход Code Infinity здесь , который также использовал оболочку для динамического связывания с файлами ресурсов.Здесь событие INotifyPropertyChanged информирует ваши элементы пользовательского интерфейса о новом файле связанных ресурсов, когда языковой стандарт был изменен.

Вы начинаете реализовывать BindingExtenstion:

public class LocalizationExtension : Binding
{
    public LocalizationExtension(string name) : base("[" + name + "]")
    {
        this.Mode = BindingMode.OneWay;
        this.Source = TranslationSource.Instance;
    }
}

Затем вам нужно реализоватьсоединение между ResourceManager и CultureInfo, которое реализовано как одноэлементный для обеспечения синхронизированного доступа.Он определяет источник для связанного элемента, а также запускает событие INotifyPropertyChanged` при изменениях локализации:

public class TranslationSource : INotifyPropertyChanged
{
    private static readonly TranslationSource instance = new TranslationSource();

    public static TranslationSource Instance
    {
        get { return instance; }
    }

    private readonly ResourceManager resManager = Resources.Strings.Resources.ResourceManager;
    private CultureInfo currentCulture = null;

    public string this[string key]
    {
        get { return this.resManager.GetString(key, this.currentCulture); }
    }

    public CultureInfo CurrentCulture
    {
        get { return this.currentCulture; }
        set
        {
            if (this.currentCulture != value)
            {
                this.currentCulture = value;
                var @event = this.PropertyChanged;
                if (@event != null)
                {
                    @event.Invoke(this, new PropertyChangedEventArgs(string.Empty));
                }
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Обратите внимание, что ваши локализованные файлы ресурсов (например, Resource.resx, Resource.en-US.resx)в папке <Project>/Resources/Strings/Resources/ в противном случае вам нужно обновить эту часть кода.

Теперь вы можете использовать эту новую привязку:

<Label Foreground="{StaticResource ApplicationForgroundColor}" FontSize="21"
       Content="{util:Localization title}"/>

Чтобы изменить языковой стандарт во время выполнения, вам необходимо установить:

public static void SetLanguage(string locale)
{
    if (string.IsNullOrEmpty(locale)) locale = "en-US";
    TranslationSource.Instance.CurrentCulture = new System.Globalization.CultureInfo(locale);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...