wpf xaml globalization multilingual

Multilenguaje en WPF



xaml globalization (4)

Josh Smith escribió un tutorial en profundidad sobre su método preferido para esto: Crear un asistente internacionalizado en WPF .

Puede apuntar hacia un gran rediseño (es una solución MVVM ), pero el uso de MVVM parece valer la pena por otras razones también.

¿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 trabajara solo en el problema principal y olvidé los problemas de lang.


Sigue estos pasos:

1) Coloque todos los fragmentos de 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) Usa las partes de texto de la tabla de 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 a través de XAML ):

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

4) Cambiar 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); }



Estoy usando la extensión de localización de WPF . Es una manera 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)
  • apoya el forzamiento de la cultura (por ejemplo, "esto tiene que ser inglés todo el tiempo")
  • Funciona con propiedades de dependencia normales.
  • trabaja 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 valores localizados a controles dinámicos generados
  • implementa INotifyPropertyChanged para uso avanzado
  • admite el formato de cadena, por ejemplo, "this is the ''{0}'' value"
  • admite valores de prefijo y sufijo (actualmente con la extensión LocText )
  • Se usa en sistemas productivos (como mi producto de relaciones públicas)
  • el cambio del idioma al tiempo de ejecución no afecta a la división 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 ) (se extiende LocalizeExtension )
  • ha incorporado soporte para Text , Text superior, Text inferior, Image , Brush , Double y Thickness
  • no afecta ninguna pérdida de memoria
  • deja la propiedad UID intacta
  • ofrece una IFormatProvider SpecificCulture para usar como IFormatProvider (por ejemplo, (123.20).ToString(LocalizeDictionary.SpecificCulture) = "123.20" o "123,20" )
  • ofrece algunas funcionalidades para verificar y obtener valores de recursos en el código detrás
  • no altera la cultura en Thread.CurrentCulture o Thread.CurrentUICulture (se puede cambiar fácilmente)