web-dev-qa-db-fra.com

C # change le langage de l'application par programmation en temps réel UWP

Dans mon application, pour chaque langue, les ressources sont stockées séparément et sont affichées en fonction du type d'environnement linguistique. Je veux changer la langue dans les paramètres de l'application. Comment est-ce que je réalise qu'après la sélection de la langue, l'applique instantanément dans l'interface utilisateur?

14
AlexeySRG

Nous pouvons utiliser ApplicationLanguages.PrimaryLanguageOverride pour modifier la langue pendant l'exécution sans redémarrer l'application.

Par exemple: "en" et "fr" sont pris en charge dans les deux langues, le message localisé apparaîtra dans le bloc de texte.

  1. Ajouter en utilisant Windows.Globalization;

  2. Changer la langue par défaut de "en" à "fr" par

    ApplicationLanguages.PrimaryLanguageOverride = "fr";
    
  3. Revenez à la page actuelle pour actualiser l'interface utilisateur. 

    Frame.Navigate(this.GetType());
    

Notez que vous devez comparer PrimaryLanguageOverride avec la culture système pour définir la langue du prochain lancement de l'application, car le paramètre PrimaryLanguageOverride est conservé. Et si vous avez activé le cache de pages, lorsque vous appliquez une autre langue à la volée, vous devez vider le cache en définissant d'abord Frame.CacheSize = 0;, puis en le réinitialisant.

27
Alan Yao - MSFT

Quelques ajouts à la réponse d'Alan Yao. Il manque une pièce: Après avoir défini le Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride et avant de revenir à la page actuelle, vous devez appeler ces deux fonctions:

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

Ainsi, vous n'aurez pas besoin de la solution de contournement Task.Delay() mentionnée par Michael Woolsey.

Une dernière étape importante: lors de la création d’un package Store, vous devez vous assurer de définir le paramètre "Générer un ensemble d’applications" sur "Jamais". Raison de cet article :

Parce que sinon, cela va créer un paquet. Cela signifie qu'il va couper votre application en différentes parties pour optimiser le téléchargement. Seulement les parties pertinentes pour les appareils seront téléchargées. Pour Par exemple, si les actifs sont dans une résolution différente, cela ne fera que téléchargez ceux qui conviennent à l'appareil. Même chose pour langues, il ne téléchargera que le fichier de ressources correspondant au fichier langue de l'appareil. Donc, si vous essayez de changer de langue, cela tombera retomber toujours sur la même langue de base, car les autres ne le sont pas installée.

5
Péter Bozsó

@ThisWillDoIt et @Herdo

J'ai ajouté un délai pour que la "première" fois que cela fonctionne dans ma situation:

Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = languageCode;

await Task.Delay(100);

Frame.Navigate(this.GetType());

J'espère que cela aide à travailler pour vous.

4
Michael Woolsey

Il existe une page MSDN qui décrit la nouvelle fonctionnalité relative à Language from Windows 8.1.

Après avoir modifié le

ApplicationLanguages.PrimaryLanguageOverride = "en-US";

J'ai regardé la propriété resourceContext.Languages[0] afin de lancer l'événement PropertyChanged de mon LanguageManager, qui était une StaticResources déclarée dans App.xaml avec 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);
        }
    }

La while (true) était juste pour le test, en fait il vaut mieux s’échapper par une "sauvegarde", parce que 

Ces exigences peuvent varier en fonction du cadre d'interface utilisateur utilisé par l'application et il peut être nécessaire de redémarrer l'application.

2
Yang C

Malheureusement, aucune des réponses ci-dessus n'a aidé si NavigationCacheMode avait pour valeur "Required" pour la page. Voici le code qui a résolu mon problème.

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