Pregunta

¿Puede recomendar una buena manera de implementar un sistema multilenguaje para una aplicación WPF? El método que estoy usando ahora involucra 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 adicional. Me gustaría dejar que el programador trabaje solo en el problema principal y olvidó los problemas de idioma.

¿Fue útil?

Solución

Estoy utilizando la Extensión de localización de WPF . Es una forma realmente fácil de localizar cualquier tipo de DependencyProperty en DependencyObject s.

  • está en un estado estable real
  • admite el estilo de escritura similar a un enlace como Text = {LocText ResAssembly: ResFile: ResKey}
  • funciona con el mecanismo .resx-fallback (por ejemplo, en-us - > en - > cultura independiente)
  • admite el forzamiento de la cultura (por ejemplo, " esto tiene que ser inglés todo el tiempo ")
  • funciona con propiedades de dependencia normales
  • funciona con plantillas de control
  • se puede usar en XAML (realmente: P) sin ningún espacio de nombres adicional
  • se puede usar en el código detrás para vincular los valores localizados a los controles dinámicos generados
  • implementa INotifyPropertyChanged para uso avanzado
  • admite el formato de cadena, por ejemplo, " este es el valor '{0}' "
  • admite los valores de prefijo y sufijo (actualmente con la extensión LocText )
  • está en uso en sistemas productivos (como mi producto de relaciones públicas)
  • el cambio del idioma al tiempo de ejecución afecta a NO intervalo de tiempo
  • se puede usar con cualquier archivo de recursos ( .resx ) en todos los ensamblajes (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 especial de localización ")
  • está disponible en tiempo de diseño (MS Expression Blend, MS Visual Studio 2008 (Normal y SP1)
  • el cambio del idioma elegido es posible en tiempo de diseño
  • puede localizar cualquier tipo de tipo de datos, siempre que exista un convertidor ( TypeConverter ) ya que existe (se extiende LocalizeExtension )
  • ha incorporado soporte para Text , Text superior, Text inferior, Image s, Brush es, Double y Thickness
  • no afecta ninguna pérdida de memoria
  • deja intacta la propiedad UID
  • ofrece un SpecificCulture para usar como IFormatProvider (por ejemplo, (123.20) .ToString (LocalizeDictionary.SpecificCulture) = " 123.20 " o " 123,20 " )
  • ofrece algunas funciones para verificar y obtener valores de recursos en el código que se encuentra detrás
  • no altera la cultura en Thread.CurrentCulture o Thread.CurrentUICulture (se puede cambiar fácilmente)

Otros consejos

Sigue estos pasos:

1) Coloque todos los fragmentos String en un archivo de recursos separado.

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) Haga copias para cada idioma y agréguelas (traducidas) a los diccionarios combinados. No olvide 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 último archivo de recursos con cadenas se utilizará para reemplazar las partes de texto en el código.

3a) Use las partes de 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) Cargue el recurso desde el código (solo use este código si no desea establecerlo mediante XAML ):

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

4) Cambie a una nueva cultura al 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);

}

Josh Smith escribió un tutorial detallado sobre su método preferido para esto: Creando un Asistente internacionalizado en WPF .

Puede apuntar hacia un gran rediseño (es una solución MVVM ), pero usar MVVM también vale la pena por otras razones.

Usando este artículo, me las arreglé para usar fácilmente los archivos de recursos para manejar ventanas WPF multilingües. http://www.codeproject.com/KB/WPF/WPF_Resx_Localization.aspx Deberías darle un cheque porque es realmente simple y efectivo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top