2009-05-02 8 views
19

Si può consigliare un buon modo per implementare un sistema multilingue per un'app WPF? Il metodo che sto usando adesso include XML, classi e un'estensione xaml. Funziona bene nella maggior parte dei casi, ma quando devo trattare con etichette dinamiche o testo dinamico in generale richiede uno sforzo extra. Vorrei lasciare che il programmatore lavorasse solo nel problema principale e ha dimenticato i problemi del lang.Multilingua in WPF

risposta

17

Sto usando il WPF Localization Extension. È un modo davvero semplice per localizzare qualsiasi tipo di DependencyProperty su DependencyObject s.

  • è in un vero e proprio stato stabile
  • supporta-come legare stile di scrittura come Text = {LocText ResAssembly:ResFile:ResKey}
  • opere con il meccanismo RESX-fallback (ad esempio it-it -> it -> cultura indipendente)
  • supporta la forzatura della cultura (es"Questo deve essere inglese tutto il tempo")
  • opere con normali proprietà di dipendenza
  • opere con modelli di controllo
  • possono essere utilizzati in XAML (davvero: P) senza alcun namespace aggiuntivi
  • possono essere utilizzati in codice dietro per associare valori localizzati a controlli dinamici
  • strumenti INotifyPropertyChanged per uso avanzato
  • supporta la formattazione di stringhe ad es. "this is the '{0}' value"
  • supporta i valori prefisso e suffisso (attualmente con LocText estensione)
  • è in uso nei sistemi produttivi (come il mio prodotto di pubbliche relazioni)
  • commutazione della lingua per runtime colpisce NO timeslice
  • può essere utilizzato con qualsiasi file di risorse (.resx) in tutte le assemblee (anche la dinamica caricata uno in fase di esecuzione)
  • non ha bisogno di alcun processo di inizializzazione (come "chiamata xyz per registrare un dizionario Localizzare speciale")
  • .210
  • è disponibile in fase di progettazione (MS Expression Blend, MS Visual Studio 2008 (Normale e SP1)
  • cambio della lingua scelta è possibile in fase di progettazione
  • può localizzare qualsiasi tipo di tipo di dati, fino a quando un convertitore (TypeConverter) perché esiste (estende LocalizeExtension)
  • ha un supporto incorporato per Text, superiore Text, inferiori Text, Image s, Brush es, Double e Thickness
  • non influisce alcun perdite di memoria
  • lascia intatto l'immobile
  • da 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 sul Thread.CurrentCulture o Thread.CurrentUICulture (può essere modificato facilmente)
+6

nessuna documentazione o tutorial su come utilizzare questo? –

+1

è ora disponibile una documentazione http://wpflocalizeextension.codeplex.com/documentation – SeriousM

32

procedere come segue:

1) Mettere tutti String frammenti 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) Fai copie per ogni lingua e li (tradotto) aggiungere 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 le stringhe sarà utilizzato per sostituire le parti di testo nel codice.

3a) utilizzare 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) caricare la risorsa dal codice (usare solo questo codice se non lo fai desidera impostare tramite XAML):

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

4) Passa alla 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); 

} 
+0

Ama il tuo suggerimento. Cose da aggiungere: penso che possiamo rendere l'applicazione commutabile in runtime usando '{StaticResource resKey}' –

+4

In realtà, basta specificare {Risorsa risorse dinamiche} ovunque si utilizzino le risorse, quindi in qualsiasi momento al runtime, chiamare SelectCulture (cultura) metodo sopra e aggiornerà tutte le tue stringhe alla nuova cultura in modo dinamico. Invece di: string str = FindResource ("All_Vehicles"). ToString(); Usa: Application.Current.Resources ["All_Vehicles"] come stringa – Curtis

+0

C'è un modo per cambiarlo durante il tempo di esecuzione? – albatross