Question

Pouvez-vous recommander un bon moyen d'implémenter un système multilingue pour une application WPF? La méthode que j'utilise actuellement implique XML, des classes et une extension xaml. Cela fonctionne bien dans la plupart des cas, mais lorsque je dois traiter des étiquettes dynamiques ou du texte dynamique en général, cela demande un effort supplémentaire. Je voudrais laisser le programmeur travailler uniquement sur le problème principal et oublier les problèmes de lang.

Était-ce utile?

La solution

J'utilise la extension de localisation WPF . C'est un moyen très simple de localiser n'importe quel type de DependencyProperty sur DependencyObject .

  • est dans un état réellement stable
  • prend en charge le style d'écriture de type reliure, tel que Text = {ResetAssembly: ResFile: ResKey} de LocText}
  • fonctionne avec le mécanisme .resx-fallback (par exemple, en-us - > en - > culture indépendante)
  • prend en charge le forçage de la culture (par exemple, "cela doit être en anglais tout le temps")
  • fonctionne avec les propriétés de dépendance normales
  • fonctionne avec les modèles de contrôle
  • peut être utilisé dans XAML (vraiment: P) sans aucun espace de nom supplémentaire
  • peut être utilisé dans code behind pour lier des valeurs localisées à des contrôles générés dynamiques
  • implémente INotifyPropertyChanged pour une utilisation avancée
  • prend en charge le formatage de chaîne, par exemple. "il s'agit de la valeur '{0}'"
  • prend en charge les valeurs de préfixe et de suffixe (actuellement avec l'extension LocText )
  • est utilisé dans des systèmes productifs (comme mon produit de relations publiques)
  • le passage de la langue à l'exécution affecte NON la tranche de temps
  • peut être utilisé avec n’importe quel fichier de ressource ( .resx ) dans tous les assemblys (également celui chargé dynamique au moment de l’exécution)
  • ne nécessite aucun processus d'initialisation (comme "appelez xyz pour enregistrer un dictionnaire de localisation spécial")
  • est disponible au moment du design (MS Expression Blend, MS Visual Studio 2008 (Normal et SP1)
  • le changement de la langue choisie est possible à la conception
  • peut localiser n'importe quel type de type de données, tant qu'un convertisseur ( TypeConverter ) existe (étend le LocalizeExtension )
  • prend en charge les éléments Text , en haut Texte , en bas Texte , Image s, Brosse , Double et Épaisseur
  • n'affecte aucune fuite de mémoire
  • laisse la propriété UID intacte
  • propose un SpecificCulture à utiliser comme IFormatProvider (par exemple, (123.20) .ToString (LocalizeDictionary.SpecificCulture) = "123.20" ou " 123,20 " )
  • offre des fonctionnalités pour vérifier et obtenir les valeurs des ressources dans le code derrière
  • ne modifie pas la culture sur Thread.CurrentCulture ou Thread.CurrentUICulture (peut être modifié facilement)

Autres conseils

Suivez ces étapes:

1) Placez tous les fragments String dans un fichier de ressources séparé.

Exemple: StringResources.xaml :

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">

    <!-- String resource that can be localized -->
    <system:String x:Key="All_Vehicles">All Vehicles</system:String>

</ResourceDictionary>

2) Créez des copies pour chaque langue et ajoutez-les (traduites) aux dictionnaires fusionnés. N'oubliez pas d'ajouter le code ISO du pays pour faciliter les choses.

Exemple App.xaml :

<Application x:Class="WpfStringTables.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
    <Application.Resources>
        <ResourceDictionary >
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="StringResources.de-DE.xaml" />
                <ResourceDictionary Source="StringResources.nl-NL.xaml" />
                <ResourceDictionary Source="StringResources.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Le dernier fichier de ressources avec des chaînes sera utilisé pour remplacer les parties de texte dans le code.

3a) Utilisez les parties de texte de la table String :

Exemple Window1.xaml :

<Window x:Class="WpfStringTables.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
    <Grid>
        <Button Margin="51,82,108,129" Name="AllVehiclesButton" 
                Content="{StaticResource All_Vehicles}"/>
    </Grid>
</Window>

3b) Chargez la ressource à partir du code (utilisez ce code uniquement si vous ne souhaitez pas définir via XAML ):

void PageLoad()
{
  string str = FindResource("All_Vehicles").ToString();
}

4) Basculer vers une nouvelle culture au début de l'application:

Codesnippet from App.xaml.cs :

public static void SelectCulture(string culture)    
{      
    if (String.IsNullOrEmpty(culture))
        return;

    //Copy all MergedDictionarys into a auxiliar list.
    var dictionaryList = Application.Current.Resources.MergedDictionaries.ToList();

    //Search for the specified culture.     
    string requestedCulture = string.Format("StringResources.{0}.xaml", culture);
    var resourceDictionary = dictionaryList.
        FirstOrDefault(d => d.Source.OriginalString == requestedCulture);

    if (resourceDictionary == null)
    {
        //If not found, select our default language.             
        requestedCulture = "StringResources.xaml";
        resourceDictionary = dictionaryList.
            FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
    }

    //If we have the requested resource, remove it from the list and place at the end.     
    //Then this language will be our string table to use.      
    if (resourceDictionary != null)
    {
        Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
        Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
    }

    //Inform the threads of the new culture.     
    Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);

}

Josh Smith a écrit un didacticiel approfondi sur sa méthode préférée pour ce faire: Création d'un Assistant internationalisé dans WPF .

Cela pourrait vous amener à une refonte importante (il s'agit d'une solution MVVM ), mais utiliser MVVM semble valoir le coup pour d’autres raisons également.

À l'aide de cet article, j'ai réussi à utiliser facilement des fichiers de ressources pour gérer des fenêtres WPF multilingues. http://www.codeproject.com/KB/WPF/WPF_Resx_Localization.aspx Vous devriez lui donner un chèque parce que c'est vraiment simple et efficace.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top