Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

  • Добавить с помощью Windows.Globalization;

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

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

    Frame.Navigate(this.GetType());
    

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

Ответ 2

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

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

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

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

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

Ответ 3

@ThisWillDoIt и @Herdo

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

Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = languageCode;

await Task.Delay(100);

Frame.Navigate(this.GetType());

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

Ответ 4

Существует страница 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) был просто для теста, на самом деле лучше избегать "резервной копии", потому что

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

Ответ 5

К сожалению, ни один из приведенных выше ответов не помог, если для страницы 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;