2009-05-02 24 views
19

¿Puede recomendar una buena manera de implementar un sistema multilenguaje para una aplicación WPF? El método que estoy usando ahora incluye XML, clases y una extensión xaml. Funciona bien en la mayoría de los casos, pero cuando tengo que lidiar con etiquetas dinámicas o texto dinámico en general, requiere un esfuerzo extra. Me gustaría dejar que el programador trabaje solo en el problema principal y olvide los problemas de idioma.Multilenguaje en WPF

Respuesta

17

Estoy usando el WPF Localization Extension. Es una manera muy fácil de localizar cualquier tipo de DependencyProperty en DependencyObject s.

  • está en un estado estable verdadera
  • apoya el estilo de unión similar a la escritura como Text = {LocText ResAssembly:ResFile:ResKey}
  • obras con el mecanismo de repliegue Resx-(por ejemplo, en-us -> en -> cultura independiente)
  • apoya el forzamiento de la cultura (p. ej."Esto tiene que ser Inglés todo el tiempo")
  • obras con las propiedades de dependencia normales
  • trabajos con las plantillas de control
  • se pueden utilizar en XAML (de verdad: P) sin ningún tipo de espacios de nombres adicionales
  • pueden utilizarse en código detrás para vincular los valores localizados a controles generados dinámicos
  • implementa INotifyPropertyChanged para uso avanzado
  • admite el formato de cadenas, por ejemplo "this is the '{0}' value"
  • soporta valores de prefijo y sufijo (en la actualidad con LocText extensión)
  • está en uso en los sistemas productivos (como mi producto de relaciones públicas)
  • conmutación de la lengua a tiempo de ejecución afecta NO porción de tiempo
  • puede haber utilizado con cualquier archivo de recursos (.resx) en todos los ensamblados (también el dinámico cargado en tiempo de ejecución)
  • no necesita ningún proceso de inicialización (como "llamar a xyz para registrar un diccionario de localización especial")
  • está disponible en tiempo de diseño (MS Expression Blend, MS Visual Studio 2008 (Normal y SP1)
  • cambio de la lengua elegida es posible en tiempo de diseño
  • puede localizar cualquier tipo de tipo de datos, siempre y cuando un convertidor (TypeConverter) para los que existe (se extiende LocalizeExtension)
  • tiene soporte para Text, superior Text, inferiores Text, Image s, Brush eS, Double y Thickness
  • no afecta a ninguna pérdidas de memoria
  • deja la propiedad UID intacta
  • ofrece SpecificCulture para usar como IFormatProvider (por ej. (123.20).ToString(LocalizeDictionary.SpecificCulture) = "123.20" o "123,20")
  • ofrece algunas funciones para comprobar y obtener valores de los recursos en el código detrás
  • no altera la cultura en Thread.CurrentCulture o Thread.CurrentUICulture (puede ser cambiado fácilmente)
+6

¿no hay documentación o tutorial sobre cómo usar esto? –

+1

una documentación ahora está disponible http://wpflocalizeextension.codeplex.com/documentation – SeriousM

32

siga estos pasos:

1)String Colocar todos los fragmentos en un archivo de recursos independiente.

Ejemplo: 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) hacer copias para cada idioma y añadirlos (traducido) a los diccionarios fusionadas. No olvides agregar el código ISO del país para facilitar las cosas.

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

El archivo de último recurso con cuerdas se usará para reemplazar partes de texto en el código.

3a) Use las partes del texto de la tabla String:

Ejemplo 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) cargar el recurso de código (Sólo utilice este código si no lo hace desea establecer a través de XAML):

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

4) Cambiar a la nueva cultura en el inicio de la aplicación:

Codesnippet de 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

Me encanta su sugerencia. Cosas para agregar: creo que podemos hacer que la aplicación se pueda cambiar en el tiempo de ejecución usando '{StaticResource resKey}' –

+4

En realidad, simplemente especifique {DynamicResource resKey} donde quiera que use los recursos, luego, en tiempo de ejecución en cualquier momento, llame a SelectCulture (culture) método anterior y actualizará todas sus cadenas a la nueva cultura de forma dinámica. En lugar de: string str = FindResource ("All_Vehicles"). ToString(); Uso: Application.Current.Resources ["All_Vehicles"] como cadena – Curtis

+0

¿Hay alguna forma de cambiarlo durante el tiempo de ejecución? – albatross