Свойство привязки текстового блока изменено, не работает в UWP - PullRequest
1 голос
/ 07 ноября 2019

Я пытаюсь добиться простого примера «нажмите кнопку, чтобы изменить язык приложения и все зависимые строки». (Вы можете увидеть весь код в этом репозитории GitHub )

В этом примере у меня есть три TextBlock и одна кнопка, привязанная к моему языку. Ресурсы:

Resources hierarchy

И:

<StackPanel
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    Orientation="Vertical">

    <TextBlock
        HorizontalAlignment="Center"
        FontSize="20"
        Text="{Binding Source={StaticResource Localized}, Path=[A]}" />
    <TextBlock
        HorizontalAlignment="Center"
        FontSize="20"
        Text="{Binding Source={StaticResource Localized}, Path=[B]}" />
    <TextBlock
        HorizontalAlignment="Center"
        FontSize="20"
        Text="{Binding Source={StaticResource Localized}, Path=[C]}" />

    <Button
        x:Name="btnChangeLanguage"
        Margin="10"
        Padding="10"
        Click="btnChangeLanguage_Click"
        Content="{Binding Source={StaticResource Localized}, Path=[Change]}" />

</StackPanel>

Как вы можете видеть, я выразил связывание TextBlock (s) с: Text="{Binding Source={StaticResource Localized}, Path=[A]}"

Локализовано типа LocalizedStrings, и это статическое свойство класса App:

public class LocalizedStrings : INotifyPropertyChanged
{
    private readonly ResourceLoader _resources;
    private readonly LocalizationHelper _localizationHelper;

    public event PropertyChangedEventHandler PropertyChanged;

    public LocalizedStrings()
    {
        _resources = ResourceLoader.GetForViewIndependentUse();
        _localizationHelper = App.LocalizationHelper;
        _localizationHelper.OnLocalizationChange += _localizationHelper_OnLocalizationChange;
    }

    public string this[string key]
    {
        get
        {
            return _resources.GetString(key);
        }
    }

    private void _localizationHelper_OnLocalizationChange(object sender, System.EventArgs e)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(string.Empty));
    }
}

И самая интересная часть LocalizationHelper просто:

public void ChangeLocalizationTo(string cultureCode)
{
    Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = cultureCode;
    OnLocalizationChange?.Invoke(null, new PropertyChangedEventArgs(string.Empty));
}

Наконец,код кнопки MainPage:

private void btnChangeLanguage_Click(object sender, RoutedEventArgs e)
{
    if (LocalizationHelper.IsCultureItalian(App.LocalizationHelper.GetCurrentLocalizationCode()))
        App.LocalizationHelper.ChangeLocalizationTo("en-US");
    else App.LocalizationHelper.ChangeLocalizationTo("it-IT");
}

Привязки работают правильно , но они привязывают только в первый раз и никогда не обновляются. Итак, я запускаю приложение, я вижу строки (также во время разработки), но когда я нажимаю кнопку, ничего не происходит. Кажется, что OnLocalizationChange?.Invoke(null, new PropertyChangedEventArgs(string.Empty)); (который вызывается) не позволяет приложению вызывать свойство для получения перевода. (Обратите внимание, что я использовал string.Empty в качестве имени свойства, чтобы уведомить, что все свойства в этом классе изменены)

«Забавно» то, что один и тот же идентичный пример, созданный с WPF, работает отлично!

WPF Example

Это заставляет меня думать, что с логикой связывания двух платформ существует несколько разное поведение.

Я уже пытался поставитьMode=OneWay привязка, но она не работает.

(Вы можете увидеть весь код в этом репозитории GitHub )

1 Ответ

2 голосов
/ 07 ноября 2019

После изменения PrimaryLanguage вам необходимо обновить страницу вручную. Пожалуйста, добавьте следующий код в метод btnChangeLanguage_Click.

private void btnChangeLanguage_Click(object sender, RoutedEventArgs e)
{
    if (LocalizationHelper.IsCultureItalian(App.LocalizationHelper.GetCurrentLocalizationCode()))
        App.LocalizationHelper.ChangeLocalizationTo("en-US");
    else App.LocalizationHelper.ChangeLocalizationTo("it-IT");

    //refresh current page
    Frame.Navigate(this.GetType());
}

Обновление

Я думал, что мог бы избежать перезагрузки страницы, полагаясь на связывание

Если вы хотите обновить свою привязку, вы можете изменить текст данных страницы на новый объект, и нам нужно переписать привязку xaml, как показано ниже.

Xaml

<StackPanel
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    Orientation="Vertical">

    <TextBlock
        HorizontalAlignment="Center"
        FontSize="20"
        Text="{Binding [A]}" />
    <TextBlock
        HorizontalAlignment="Center"
        FontSize="20"
        Text="{Binding [B]}" />
    <TextBlock
        HorizontalAlignment="Center"
        FontSize="20"
        Text="{Binding [C]}" />

    <Button
        x:Name="btnChangeLanguage"
        Margin="10"
        Padding="10"
        Click="btnChangeLanguage_Click"
        Content="{Binding [Change]}" />

</StackPanel>

Код сзади

 public MainPage()
 {
     InitializeComponent();
     this.DataContext = new LocalizedStrings();
 }

 private async void btnChangeLanguage_Click(object sender, RoutedEventArgs e)
 {
     if (LocalizationHelper.IsCultureItalian(App.LocalizationHelper.GetCurrentLocalizationCode()))
         App.LocalizationHelper.ChangeLocalizationTo("en-US");
     else App.LocalizationHelper.ChangeLocalizationTo("it-IT");
     await Task.Delay(100); // used to prepare the resource.
     this.DataContext = new LocalizedStrings();
 }
...