Este artículo proviene de un motor de traducción automática.

Localización de Silverlight

Consejos y trucos para cargar recursos de configuración regional de Silverlight.

Matthew Delisle

Descargar el ejemplo de código

Silverlight es un marco excelente para crear aplicaciones de Internet enriquecidas (RIA), pero aún no proporciona la compatibilidad sólida para la localización que disfrute en otros componentes de Microsoft.NET Framework.Silverlight tiene archivos .resx, una clase ResourceManager simple y un elemento en el archivo de proyecto.Pero después de que se encuentra en su propio.No hay ninguna extensión de marcado personalizado y no es compatible con la clase DynamicResource.

En este artículo mostraré cómo resolver todos estos problemas.Presentaré una solución que permitirá al cargar conjuntos de recursos en tiempo de ejecución, utilice cualquier formato para almacenar recursos, cambiar recursos sin volver a compilar y demostrar la carga diferida de recursos de desarrollador.

En este artículo se divide en tres partes.En primer lugar, desarrollaré una aplicación sencilla mediante el proceso de localización detallado por Microsoft.A continuación, presentaré otra solución de localización que tiene algunas ventajas sobre el proceso estándar.Por último, podrá redondear la solución con una explicación de los componentes de back-end necesarios para completar la solución.

El proceso de localización estándar

Comenzaré por crear una aplicación de Silverlight que utiliza el proceso de localización descrito por Microsoft.Una descripción detallada del proceso está disponible en MSDN.Microsoft.com/library/cc838238(VS.95).

La interfaz de usuario contiene un objeto TextBlock y una imagen, como se muestra en figura 1.

image: The App

Figura 1 la aplicación

El proceso de localización descrito por Microsoft utiliza los archivos .resx para almacenar los datos de recursos.Los archivos .resx están incrustados en el ensamblado principal o un ensamblado satélite y cargar sólo una vez, al iniciarse la aplicación.Puede crear aplicaciones dirigidas a determinados idiomas modificando el elemento SupportedCultures en el archivo de proyecto.Se traducirá esta aplicación de ejemplo para dos idiomas, inglés y francés.Después de agregar los archivos de recursos de dos y dos imágenes de indicadores, la estructura de proyecto es similar a figura 2.

image: Project Structure After Adding .resx Files

Figura 2 estructura de proyecto después de agregar los archivos .resx

Se ha cambiado la acción de generación para las imágenes al contenido, de modo que puedo hacer referencia a las imágenes mediante una sintaxis menos detallada.Vamos a agregar dos entradas para cada archivo.TextBlock que se hace referencia a través de una propiedad denominada de bienvenida y el control de imagen que se hace referencia a través de una propiedad denominada FlagImage.

Cuando se crean archivos de recursos en una aplicación de Silverlight, el modificador predeterminado para la clase de recursos generados es interno.Por desgracia, XAML no puede leer a los miembros internos, incluso si está ubicados en el mismo ensamblado.Para remediar esta situación, los modificadores de la clase generada se deben cambiar a público.Esto puede hacerse en la vista Diseño del archivo de recursos.El menú desplegable de modificador de acceso le permite designar el ámbito de la clase generada.

Una vez que los archivos de recursos están preparados, deberá enlazar los recursos en XAML.Para ello, se crea una clase contenedora con un campo estático, que hace referencia a una instancia de la clase de recurso.La clase es tan sencilla como esto:

public class StringResources {
  private static readonly strings strings = new strings();
  public strings Strings {  get { return strings; } }
}

Para hacer que la clase puede tener acceso desde XAML, tiene que crear una instancia. En este caso, crearé la instancia de la clase App para que sea accesible en todo el proyecto:

<Application.Resources>
  <local:StringResources x:Key="LocalizedStrings"/>
</Application.Resources>

Ahora es posible el enlace de datos en XAML. El código XAML para el TextBlock y la imagen tiene este aspecto:

<StackPanel Grid.ColumnSpan="2" Orientation="Horizontal" 
  HorizontalAlignment="Center">
  <TextBlock Text="{Binding Strings.Welcome, Source={StaticResource LocalizedStrings}}" 
    FontSize="24"/>
</StackPanel>
<Image Grid.Row="1" Grid.ColumnSpan="2" 
  HorizontalAlignment="Center"
  Source="{Binding Strings.FlagImage, Source={StaticResource LocalizedStrings}}"/>

La ruta de acceso es la propiedad de cadena seguida de la clave de la entrada de recurso. El origen es la instancia del contenedor StringResources desde la clase App.

Establecer la referencia cultural

Existen tres opciones de configuración de la aplicación que se deben configurar para que la aplicación recoger la configuración de la referencia cultural del explorador y mostrar la referencia cultural adecuada.

El primer valor es el elemento de SupportedCultures en el archivo .csproj. Actualmente no hay ningún cuadro de diálogo de Visual Studio para editar la configuración, por lo que se debe editar manualmente el archivo de proyecto. Puede editar un archivo de proyecto abriéndolo fuera de Visual Studio, o descargar el proyecto y seleccionando Editar en el menú de contexto dentro de Visual Studio.

Para habilitar el inglés y francés para esta aplicación, el valor del elemento SupportedCultures tiene este aspecto:

<SupportedCultures>fr</SupportedCultures>

Los valores de las referencias culturales están separados por comas. No es necesario especificar la referencia cultural neutra;se compila en el archivo DLL principal.

Estos pasos son necesarios para recoger la configuración de idioma del explorador. En el objeto de Silverlight incrustado en la página Web, se debe agregar un parámetro. El valor de los parámetros es la actual referencia cultural de IU, procedente del servidor. Esto requiere que la página Web sea un archivo .aspx. La sintaxis del parámetro es:

<param name="uiculture" 
  value="<%=Thread.CurrentThread.CurrentCulture.Name %>" />

El último paso obligatorio en este proceso es editar el archivo web.config y agregue un elemento de globalización dentro del elemento system.web, establecer los valores de sus atributos automáticamente:

<globalization culture="auto" uiCulture="auto"/>

Como se mencionó anteriormente, una aplicación de Silverlight tiene una configuración de idioma neutro. La configuración se alcanza en la ficha de Silverlight de las propiedades del proyecto y haciendo clic en información de ensamblado. La propiedad de idioma neutral se encuentra en la parte inferior del cuadro de diálogo, como se muestra en figura 3.

image: Setting the Neutral Language

Figura 3 Configuración del idioma Neutral

Se recomienda establecer el idioma neutral en uno sin una región. Esta configuración es un recurso de reserva y es más útil si se trata de una amplia gama de configuraciones regionales posibles. Definir un idioma neutro, agrega un atributo de ensamblado para el archivo assemblyinfo.cs, similar al siguiente:

[assembly: NeutralResourcesLanguageAttribute("en")]

Después de todo eso, lo que termina con es una aplicación localizada que lee la configuración de idioma del explorador en el inicio y carga los recursos apropiados.

Un proceso de localización personalizadas

Las limitaciones del proceso de localización estándar se derivan de la utilización de los archivos .resx y de ResourceManager.La clase ResourceManager no cambia los conjuntos de recursos en tiempo de ejecución según los cambios de la referencia cultural dentro del entorno.Utilizando archivos .resx, bloquea el desarrollador en el conjunto de recursos de uno por cada idioma y inflexibilidad en el mantenimiento de los recursos.

En respuesta a estas limitaciones, echemos un vistazo a una solución alternativa que emplea los recursos dinámicos.

Para hacer que los recursos dinámicos, el Administrador de recursos debe enviar una notificación cuando cambie de conjunto de los recursos activos.Para enviar notificaciones en Silverlight, implementa la interfaz INotifyPropertyChanged.Internamente, cada conjunto de recursos será un diccionario con un tipo de clave y valor de cadena.

El marco de trabajo de prisma y el marco de extensibilidad administrada (MEF) son populares para el desarrollo de Silverlight y dividir la aplicación en varios archivos .xap estos marcos.Para la localización, cada archivo .xap necesita su propia instancia del Administrador de recursos.Para enviar notificaciones a todos los archivos .xap (todas las instancias del Administrador de recursos), es necesario realizar un seguimiento de cada instancia que se crea y recorrer en esa lista cuando las notificaciones deben enviarse.Figura 4 muestra el código de esta funcionalidad de SmartResourceManager.

Figura 4 SmartResourceManager

public class SmartResourceManager : INotifyPropertyChanged {
  private static readonly List<SmartResourceManager> Instances = 
    new List<SmartResourceManager>();
  private static Dictionary<string, string> resourceSet;
  private static readonly Dictionary<string, 
    Dictionary<string, string>> ResourceSets = 
    new Dictionary<string, Dictionary<string, string>>();
  public Dictionary<string, string> ResourceSet {
    get { return resourceSet; }
    set { resourceSet = value;
    // Notificar a todas las instancias
    foreach (var obj in Instances) {
      obj.NotifyPropertyChanged("ResourceSet");
    }
  }
}
public SmartResourceManager() {
  Instances.Add(this);
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string property) {
  var evt = PropertyChanged;
  if (evt != null) {
    evt(this, new PropertyChangedEventArgs(property));
  }
}

Como puede ver, se crea una lista estática para contener todas las instancias del recurso de administrador. El conjunto de recursos activos se almacena en el resourceSet de campo y todos los recursos que se ha cargado se almacenan en la lista de ResourceSets. En el constructor, la instancia actual se almacena en la lista de instancias. La clase implementa INotifyPropertyChanged en la forma estándar. Cuando se cambia el conjunto de recursos activos, iterar a través de la lista de instancias y del cada uno de ellos evento PropertyChanged se desencadena.

La clase de SmartResourceManager necesita una forma de cambiar la referencia cultural en tiempo de ejecución, y es tan simple como un método que toma un objeto CultureInfo:

public void ChangeCulture(CultureInfo culture) {
  if (!ResourceSets.ContainsKey(culture.Name)) {
    // cargar el conjunto de recursos
  }
  else {
    ResourceSet = ResourceSets[culture.Name];
    Thread.CurrentThread.CurrentCulture = 
      Thread.CurrentThread.CurrentUICulture = 
      culture;
  }
}

Este método comprueba si la referencia cultural solicitada se ha cargado todavía. Si no es así, carga de la referencia cultural y, a continuación, se establece como activa. Si ya se ha cargado la referencia cultural, el método simplemente establece el recurso correspondiente establecido como activo. Se omite el código para cargar un recurso por el momento.

Por integridad, también mostraré los dos métodos para cargar un recurso mediante programación (consulte figura 5). El primer método toma simplemente una clave de recurso y devuelve el recurso de la referencia cultural activa. El segundo método toma un nombre de referencia cultural y de un recurso y devuelve el recurso para esa referencia cultural específica.

Figura 5 cargar recursos

public string GetString(string key) {
  if (string.IsNullOrEmpty(key)) return string.Empty;
  if (resourceSet.ContainsKey(key)) {
    return resourceSet[key];
  }
  else {
    return string.Empty;
  }
}
public string GetString(string key, string culture) {
  if (ResourceSets.ContainsKey(culture)) {
    if (ResourceSets[culture].ContainsKey(key)) {
      return ResourceSets[culture][key];
    }
    else {
      return string.Empty;
    }
  }
  else {
    return string.Empty;
  }
}

Si ha ejecutado la aplicación ahora, todas las cadenas localizadas estaría vacías, porque no hay conjuntos de recursos se han descargado. Para cargar el conjunto inicial de recursos, voy a crear un método denominado Initialize que toma el identificador de archivo y la referencia cultural del idioma neutral. Este método debe llamarse sólo una vez durante el período de duración de la aplicación (consulte figura 6).

Figura 6 al inicializar el idioma Neutral

public SmartResourceManager() {
  if (Instances.Count == 0) {
    ChangeCulture(Thread.CurrentThread.CurrentUICulture);    
  }
  Instances.Add(this);
}
public void Initialize(string neutralLanguageFile, 
  string neutralLanguage) {
  lock (lockObject) {
    if (isInitialized) return;
    isInitialized = true;
  }
  if (string.IsNullOrWhiteSpace(neutralLanguageFile)) {
    // No neutral resources
    ChangeCulture(Thread.CurrentThread.CurrentUICulture);
  }
  else {
    LoadNeutralResources(neutralLanguageFile, neutralLanguage);
  } 
}

Enlace en XAML

Una extensión de marcado personalizado proporcionaría la sintaxis de enlace más fluida de los recursos localizados. Desafortunadamente, las extensiones de marcado personalizados no están disponibles en Silverlight. Enlace a un diccionario está disponible en Silverlight 3 y versiones posteriores, y la sintaxis tiene este aspecto:

<StackPanel Grid.ColumnSpan="2" Orientation="Horizontal" 
  HorizontalAlignment="Center">
  <TextBlock Text="{Binding Path=ResourceSet[Welcome], Source={StaticResource 
SmartRM}}" FontSize="24"/>
</StackPanel>
<Image Grid.Row="1" Grid.ColumnSpan="2" 
  HorizontalAlignment="Center" 
  Source="{Binding ResourceSet[FlagImage], Source={StaticResource SmartRM}}"/>

La ruta de acceso contiene el nombre de la propiedad de diccionario con la clave en corchetes. Si está utilizando Silverlight 2, hay dos opciones disponibles: creación de una clase de ValueConverter o emitir un objeto con establecimiento inflexible utilizando la reflexión. La creación de un objeto con establecimiento inflexible utilizando la reflexión es más allá del alcance de este artículo. Sería el código de un ValueConverter figura 7.

Figura 7 ValueConverter personalizada

public class LocalizeConverter : IValueConverter {
  public object Convert(object value, 
    Type targetType, object parameter, 
    System.Globalization.CultureInfo culture) {
    if (value == null) return string.Empty;
    Dictionary<string, string> resources = 
      value as Dictionary<string, string>;
    if (resources == null) return string.Empty;
    string param = parameter.ToString();
    if (!resources.ContainsKey(param)) return string.Empty;
    return resources[param];
  }
}

La clase LocalizeConverter toma el diccionario y el parámetro pasado y devuelve el valor de dicha clave en el diccionario. Después de crear una instancia del convertidor, la sintaxis de enlace tendría este aspecto:

<StackPanel Grid.ColumnSpan="2" Orientation="Horizontal" 
  HorizontalAlignment="Center">
  <TextBlock Text="{Binding Path=ResourceSet, Source={StaticResource SmartRM}, Converter={StaticResource LocalizeConverter}, Convert-erParameter=Welcome}" FontSize="24"/>
</StackPanel>
<Image Grid.Row="1" Grid.ColumnSpan="2" HorizontalAlignment="Center" 
  Source="{Binding ResourceSet, Source={StaticResource SmartRM}, Converter={StaticResource LocalizeConverter}, ConverterParameter=FlagImage}"/>

La sintaxis es más detallada utilizando el convertidor, aunque tiene más flexibilidad. Sin embargo, el resto del artículo, que vamos a continuar sin el convertidor, utilizando en su lugar la sintaxis de enlace de diccionario.

Valores de configuración regional Redux

Existen dos configuraciones de aplicación que se deben configurar para que la referencia cultural ser recogidas por la aplicación de Silverlight. Se trata de la misma configuración que se tratan con el proceso de localización estándar. El elemento de globalización en el archivo web.config debe tener los valores culture y uiCulture de auto:

<globalization culture="auto" uiCulture="auto"></globalization>

Además, es necesario que el objeto de Silverlight en el archivo .aspx pasarse en el valor culture de la interfaz de usuario de subproceso actual como un parámetro:

<param name="uiculture" 
  value="<%=Thread.CurrentThread.CurrentCulture.Name %>" />

Para presentar la dinámica de la localización de la aplicación, voy a agregar dos botones que facilitan el cambio de la referencia cultural, como se muestra en figura 8. El evento click del botón inglés tiene este aspecto:

(App.Current.Resources["SmartRM"] as SmartResourceManager).ChangeCulture(
  new CultureInfo("en"));

image: Culture-Change Buttons

Figura 8 botones de cambio de la referencia cultural

Con algunos datos simulada, la aplicación podría ejecutar y mostrar el idioma apropiado. Aquí, la solución permite la localización dinámica en tiempo de ejecución y es lo suficientemente extensible como para cargar los recursos mediante la lógica personalizada.

La siguiente sección se centra en rellenar el espacio restante: donde se almacenan los recursos y cómo se recuperan.

Componentes de servidor

Ahora vamos a crear una base de datos para almacenar los recursos y un servicio de Windows Communication Foundation (WCF) para recuperar esos recursos. En aplicaciones más grandes, puede que desee crear los datos y las capas empresariales, pero para este ejemplo, no va a utilizar las abstracciones.

El motivo que se ha elegido un servicio WCF es la facilidad de creación y solidez ofrecidos por WCF. El motivo que se ha elegido para almacenar los recursos en una base de datos relacional es para facilitar el mantenimiento y administración. Se podría crear una aplicación de administración que permitiría a los traductores modificar fácilmente los recursos.

Estoy utilizando SQL Server 2008 Express para esta aplicación. En el que se muestra el esquema de datos figura 9.

image: Schema for Localization Tables in SQL Server 2008 Express

Figura 9 esquema para la localización de las tablas en SQL Server 2008 Express

Una etiqueta es un nombre de grupo de recursos. El recurso de una cadena es la entidad que representa un recurso. La columna LocaleId representa el nombre de la referencia cultural que el recurso es bajo. Para la compatibilidad con el formato .resx, se agrega la columna comentario. Se agregan las columnas CreatedDate y ModifiedDate para fines de auditoría.

El recurso de una cadena puede asociarse a varias etiquetas. La ventaja de esto es que puede crear grupos específicos (por ejemplo, los recursos para una sola pantalla) y descargar sólo aquellos recursos. La desventaja es que se pueden asignar varios recursos con el mismo LocaleId, la clave y la etiqueta. En ese caso, desea escribir un desencadenador para administrar los recursos de la creación o actualización o utilizar la columna ModifiedDate al recuperar el recurso se establece para determinar cuál es el recurso más reciente.

Voy a recuperar los datos con LINQ to SQL. La primera operación de servicio tomará un nombre de referencia cultural y devolver todos los recursos asociados a esa referencia cultural. Aquí es la interfaz:

[ServiceContract]
public interface ILocaleService {
  [OperationContract]
  Dictionary<string, string> GetResources(string cultureName);
}

Ésta es la implementación:

public class LocaleService : ILocaleService {
  private acmeDataContext dataContext = new acmeDataContext();
  public Dictionary<string, string> GetResources(string cultureName) {
  return (from r in dataContext.StringResources
          where r.LocaleId == cultureName
          select r).ToDictionary(x => x.Key, x => x.Value);
  }
}

La operación simplemente busca todos los recursos cuyo LocaleId es igual al parámetro cultureName. El campo de dataContext es una instancia de la clase SQL conectado a la base de datos de SQL Server de LINQ. Eso es todo! LINQ y WCF hacen cosas tan simple.

Ahora, es momento de vincular el servicio WCF a la clase SmartResourceManager. Después de agregar una referencia de servicio a la aplicación de Silverlight, registrarme para recibir el evento completado para la operación de GetResources en el constructor:

public SmartResourceManager() {
  Instances.Add(this);
  localeClient.GetResourcesCompleted += 
    localeClient_GetResourcesCompleted;
  if (Instances.Count == 0) {
    ChangeCulture(Thread.CurrentThread.CurrentUICulture);
  } 
}

El método de devolución de llamada debe agregar el conjunto de recursos a la lista de conjuntos de recursos y que el recurso se establece el conjunto activo. El código se muestra en la figura 10.

Figura 10 Agregar recursos

private void localeClient_GetResourcesCompleted(object sender, 
  LocaleService.GetResourcesCompletedEventArgs e) {
  if (e.Error != null) {
    var evt = CultureChangeError;
    if (evt != null)
      evt(this, new CultureChangeErrorEventArgs(
        e.UserState as CultureInfo, e.Error));
  }
  else {
    if (e.Result == null) return;
    CultureInfo culture = e.UserState as CultureInfo;
    if (culture == null) return;
    ResourceSets.Add(culture.Name, e.Result);
    ResourceSet = e.Result;
    Thread.CurrentThread.CurrentCulture = 
      Thread.CurrentThread.CurrentUICulture = culture;
  }
}

El método ChangeCulture debe modificarse para realizar una llamada a la operación de WCF:

public void ChangeCulture(CultureInfo culture) {
  if (!ResourceSets.ContainsKey(culture.Name)) {
    localeClient.GetResourceSetsAsync(culture.Name, culture);
  }
  else {
    ResourceSet = ResourceSets[culture.Name];
    Thread.CurrentThread.CurrentCulture = 
      Thread.CurrentThread.CurrentUICulture = culture;
  }
}

Cargar la configuración regional neutra

Esta aplicación necesita una forma de recuperar en caso de los servicios Web no se puede contactar o tiempo de espera. Un archivo de recursos que contiene los recursos de idioma neutro debe almacenarse fuera de los servicios Web y carga al inicio. Esto le servirá como reserva y una mejora de rendimiento a través de la llamada al servicio.

Voy a crear otro constructor de SmartResourceManager con dos parámetros: una dirección URL que señala al archivo de recursos de idioma neutral y un código de referencia cultural que identifica la referencia cultural del archivo de recursos (consulte figura 11).

Figura 11 cargar la configuración regional neutra

public SmartResourceManager(string neutralLanguageFile,   string neutralLanguage) {
  Instances.Add(this);
  localeClient.GetResourcesCompleted += 
    localeClient_GetResourcesCompleted;
  if (Instances.Count == 1) {
    if (string.IsNullOrWhiteSpace(neutralLanguageFile)) {
      // hay recursos neutros
      ChangeCulture(Thread.CurrentThread.CurrentUICulture);
    }
    else {
      LoadNeutralResources(neutralLanguageFile, neutralLanguage);
    }
  }
}

Si no hay ningún archivo de recursos neutrales, se realiza el proceso normal de la llamada a la llamada WCF. El método LoadNeutralResources utiliza un cliente Web para recuperar el archivo de recursos del servidor. A continuación, se analiza el archivo y se convierte la cadena XML en un objeto de diccionario. No se mostrará el código aquí como es un poco larga y no es muy importante, pero puede encontrarla en la descarga de código para este artículo si está interesado.

Para llamar al constructor con parámetros SmartResourceManager, necesito mover la creación de instancias de la SmartResourceManager en el código subyacente de la clase App (porque Silverlight no admite XAML 2009). No se desea codificar el archivo de recursos o el código de la referencia cultural, sin embargo, por lo que tendré que crear una clase ConfigurationManager personalizada, que puede consultar en la descarga de código.

Después de integrar el ConfigurationManager en la clase App, el método de devolución de llamada de evento de inicio tiene este aspecto:

private void Application_Startup(object sender, StartupEventArgs e) {
  ConfigurationManager.Error += ConfigurationManager_Error;
  ConfigurationManager.Loaded += ConfigurationManager_Loaded;
  ConfigurationManager.LoadSettings();
}

El método de devolución de llamada de inicio ahora sirve para cargar la configuración de la aplicación y registrarse para las devoluciones de llamada. Si decide realizar una llamada de fondo de la carga de los valores de configuración, tenga cuidado de las condiciones de anticipación en el que se pueden ejecutar en. Éstos son los métodos de devolución de llamada para los eventos ConfigurationManager:

private void ConfigurationManager_Error(object sender, EventArgs e) {
  Resources.Add("SmartRM", new SmartResourceManager());
  this.RootVisual = new MainPage();
}
private void ConfigurationManager_Loaded(object sender, EventArgs e) {
  Resources.Add("SmartRM", new SmartResourceManager(
    ConfigurationManager.GetSetting("neutralLanguageFile"), 
    ConfigurationManager.GetSetting("neutralLanguage")));
  this.RootVisual = new MainPage();
}

El método de devolución de llamada de evento de Error, carga SmartResourceManager sin un idioma neutral y el método de devolución de llamada de evento Loaded carga con un lenguaje neutro.

Es necesario poner el archivo de recursos en una ubicación donde no tengo que volver a compilar nada si se puede cambiar. Voy a ponerlo en el directorio ClientBin del proyecto Web y, después de crear el archivo de recursos, voy a cambiar su extensión a .xml para que sea accesible al público y la clase WebClient puede tener acceso a él desde la aplicación de Silverlight. Dado que es accesible públicamente, no ponga ningún dato sensible en el archivo.

ConfigurationManager también se lee desde el directorio ClientBin. Busca un archivo denominado appSettings.xml y el archivo tiene este aspecto:

<AppSettings>
  <Add Key="neutralLanguageFile" Value="strings.xml"/>
  <Add Key="neutralLanguage" Value="en-US"/>
</AppSettings>

Una vez appSettings.xml y strings.xml en su lugar, ConfigurationManager y SmartResourceManager pueden trabajar conjuntamente para cargar el idioma neutral.No hay espacio para la mejora en este proceso, porque si la referencia cultural activo del subproceso es diferente del idioma neutral y el servicio Web está cerrado, referencia cultural activo del subproceso será diferente del conjunto de recursos activos.Dejaré como ejercicio para usted.

Conclusión

¿Qué no ir en este artículo fue la normalización de los recursos en el servidor.Supongamos que el recurso de fr-FR falta dos claves que tiene el recurso fr.Cuando se solicitan los recursos de fr-FR, el servicio Web debe insertar las claves que faltan desde el recurso de fr más general.

Otro aspecto que tiene incorporado esta solución que no entré está cargando los recursos por el conjunto de recursos y la referencia cultural en lugar de la referencia cultural sólo.Esto resulta útil para cargar recursos por la pantalla o por el archivo .xap.

La solución que le guíe a través de aquí le permiten hacer algunas cosas útiles, sin embargo, incluidos los conjuntos de recursos en tiempo de ejecución, utilizando cualquier formato para almacenar recursos, cambiar recursos sin volver a compilar y carga diferida de carga.

La solución presentada aquí es el propósito general y puede cambiar drásticamente la implementación y engancharse en varios puntos.Espero que esto ayuda a reducir la carga de la programación diaria.

Para leer más detallada acerca de la internacionalización, retirar el libro ".NET internacionalización: la Guía del desarrollador a la creación de aplicaciones Web y Windows Global "(Addison-Wesley, 2006), por Guy Smith-Ferrier.Smith-Ferrier también tiene un vídeo excelente en la internacionalización en su sitio Web;el vídeo se denomina "Internacionalización de Silverlight en SLUGUK")bit.LY/gJGptU).

Matthew Delisle disfruta de estudiar los aspectos de hardware y software de equipos. Su hija primera nació en 2010y él piensa que está casi listo para empezar su carrera de programación. Mantener el ritmo de Delisle a través de su blog en mattdelisle.NET.

Gracias al siguiente experto técnico para la revisión de este artículo: John brodeur