Domanda

Puoi consigliare un buon modo per implementare un sistema multilingue per un'app WPF? Il metodo che sto usando in questo momento prevede XML, classi e un'estensione xaml. Funziona bene nella maggior parte dei casi, ma quando devo occuparmi di etichette dinamiche o di testi dinamici in generale, richiede qualche sforzo in più. Vorrei lasciare che il programmatore lavorasse solo nel problema principale e abbia dimenticato i problemi di lingua.

È stato utile?

Soluzione

Sto utilizzando la Estensione di localizzazione WPF . È un modo davvero semplice per localizzare qualsiasi tipo di DependencyProperty su DependencyObject s.

  • è in uno stato reale stabile
  • supporta uno stile di scrittura vincolante come Text = {LocText ResAssembly: ResFile: ResKey}
  • funziona con il meccanismo .resx-fallback (ad es. en-us - > en - > cultura indipendente)
  • supporta il forzante culturale (ad es. " questo deve essere sempre inglese ")
  • funziona con le normali proprietà di dipendenza
  • funziona con i modelli di controllo
  • può essere utilizzato in XAML (in realtà: P) senza spazi dei nomi aggiuntivi
  • può essere utilizzato nel codice dietro per associare valori localizzati a controlli generati dinamici
  • implementa INotifyPropertyChanged per uso avanzato
  • supporta la formattazione di stringhe ad es. " questo è il valore '{0}' "
  • supporta i valori di prefisso e suffisso (attualmente con estensione LocText )
  • è in uso in sistemi produttivi (come il mio prodotto di pubbliche relazioni)
  • il passaggio dalla lingua al runtime influisce su NO timeslice
  • può essere utilizzato con qualsiasi file di risorse ( .resx ) in tutti gli assembly (anche quello dinamico caricato in fase di runtime)
  • non ha bisogno di alcun processo di inizializzazione (come " chiama xyz per registrare un dizionario di localizzazione speciale ")
  • è disponibile in fase di progettazione (MS Expression Blend, MS Visual Studio 2008 (Normal e SP1)
  • è possibile cambiare la lingua scelta in fase di progettazione
  • può localizzare qualsiasi tipo di tipo di dati, purché esista un convertitore ( TypeConverter ) (estende LocalizeExtension )
  • ha integrato il supporto per Text , Text , Text , Image , Spazzola es, Double e Thickness
  • non influisce su eventuali perdite di memoria
  • lascia intatta la proprietà UID
  • offre un SpecificCulture da utilizzare come IFormatProvider (ad es. (123.20) .ToString (LocalizeDictionary.SpecificCulture) = " 123.20 " o " 123,20 " )
  • offre alcune funzionalità per controllare e ottenere i valori delle risorse nel codice dietro
  • non altera la cultura su Thread.CurrentCulture o Thread.CurrentUICulture (può essere modificato facilmente)

Altri suggerimenti

Segui questi passaggi:

1) Posiziona tutti i frammenti String in un file di risorse separato.

Esempio: 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) Crea copie per ogni lingua e aggiungile (tradotte) ai dizionari uniti. Non dimenticare di aggiungere il codice ISO del Paese per semplificare le cose.

Esempio 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>

L'ultimo file di risorse con stringhe verrà utilizzato per sostituire le parti di testo nel codice.

3a) Utilizza le parti di testo dalla tabella String :

Esempio 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) Carica la risorsa dal codice (utilizza questo codice solo se non desideri impostare tramite XAML ):

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

4) Passa a una nuova cultura all'avvio dell'applicazione:

Codesnippet da 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 ha scritto un tutorial approfondito sul suo metodo preferito per questo: Creazione di un Procedura guidata internazionalizzata in WPF .

Potrebbe indirizzarti verso una grande riprogettazione (è una soluzione MVVM ), ma l'utilizzo di MVVM sembra valere la pena anche per altri motivi.

Usando questo articolo sono riuscito a usare facilmente i file di risorse per gestire le finestre WPF multilingue. http://www.codeproject.com/KB/WPF/WPF_Resx_Localization.aspx Dovresti dare un assegno perché è davvero semplice ed efficace.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top