it-swarm.com.ru

C # изменить язык приложения программно UWP в реальном времени

В моем приложении для каждого языка строковые ресурсы хранятся отдельно и отображаются в зависимости от типа языковой среды. Я хочу изменить язык в настройках приложения. Как я понимаю, что после выбора языка мгновенно применить его в пользовательском интерфейсе?

14
AlexeySRG

Мы можем использовать ApplicationLanguages.PrimaryLanguageOverride , чтобы изменить язык во время выполнения без перезапуска приложения.

Например: у меня есть два поддерживаемых языка «en» и «fr», локализованное сообщение будет отображаться в текстовом блоке.

  1. Добавить с помощью Windows. Глобализация;

  2. Измените язык по умолчанию с "en" на "fr" на

    ApplicationLanguages.PrimaryLanguageOverride = "fr";
    
  3. Перейдите на текущую страницу, чтобы обновить пользовательский интерфейс. 

    Frame.Navigate(this.GetType());
    

Обратите внимание, что вам нужно сравнить PrimaryLanguageOverride с системной культурой, чтобы установить язык для следующего запуска приложения, поскольку параметр PrimaryLanguageOverride сохраняется. И если у вас включен кеш страниц, когда вы применяете другой язык на лету, вам нужно очистить кеш, сначала установив Frame.CacheSize = 0;, а затем вернув его обратно.

27
Alan Yao - MSFT

Некоторое дополнение к ответу Алана Яо. Там есть один отсутствующий фрагмент: После установки Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride и перед повторным переходом на текущую страницу, вы должны вызвать эти две функции:

Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();

Таким образом, вам не понадобится обходной путь Task.Delay(), упомянутый Майклом Вулси.

Еще один важный последний шаг: при создании пакета Store вы должны убедиться, что для параметра «Создать пакет приложений» установлено значение «Никогда». Причина из эта статья :

Потому что в противном случае он создаст связку. Это значит, что он будет резать Ваше приложение на разные части для оптимизации загрузки. Только части, которые имеют отношение к устройствам, будут загружены. За Например, если есть активы в другом разрешении, это будет только скачать те, которые подходят для устройства. То же самое для языки, он будет загружать только файл ресурсов, относящийся к язык устройства. Так что если вы попытаетесь изменить язык, он упадет все еще прибегают к тому же базовому языку, потому что другие не установлены.

5
Péter Bozsó

@ThisWillDoIt и @Herdo

Я добавил задержку, чтобы «Первый» раз работал в моей ситуации:

Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = languageCode;

await Task.Delay(100);

Frame.Navigate(this.GetType());

Надеюсь, это поможет вам.

4
Michael Woolsey

Существует страница MSDN , которая описывает новое перо о языке из Windows 8.1.

После изменения

ApplicationLanguages.PrimaryLanguageOverride = "en-US";

Я наблюдал за свойством resourceContext.Languages[0], чтобы запустить событие PropertyChanged моего LanguageManager, которое было StaticResources, объявленное в App.xaml с x:Key = Loc.

    private void ButtonEn_OnClick(object sender, RoutedEventArgs e)
    {
        ApplicationLanguages.PrimaryLanguageOverride = "en-US";
        UpdateLang("en-US");
    }

    private async void UpdateLang(string newLang)
    {
        var resourceContext = Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView();

        while (true)
        {
            if (resourceContext.Languages[0] == newLang)
            {
                var loc = Application.Current.Resources["Loc"] as LanguagesManager;
                loc.ChangeLang();
                break;
            }
            await Task.Delay(100);
        }
    }

Функция while (true) была только для проверки, на самом деле ее лучше скрыть «резервной копией», потому что 

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

2
Yang C

К сожалению, ни один из приведенных выше ответов не помог, если для страницы установлено NavigationCacheMode"Required". Вот код, который решил мою проблему.

ApplicationLanguages.PrimaryLanguageOverride = language;
await Task.Delay(300);
Frame rootFrame = Window.Current.Content as Frame;
rootFrame.Content = null;
rootFrame = null;            
rootFrame = new Frame();
rootFrame.Navigate(typeof(MainPage), null);
Window.Current.Content = rootFrame;
0
SolderingIronMen