Hoy quiero hablar de algo que no es muy usado (creo) pero que por eso mismo puede ayudar a aquellos que se encuentren con el problema de no saber afrontar cómo localizar una aplicación en Silverlight que, aunque pareciera sencillo, tiene algunos entresijos que me gustaría compartir con todos.

 

Creando la aplicación Silverlight

Evidentemente, lo primero será crear la aplicación Silverlight seleccionándola de las plantillas disponibles en Visual Studio, en mi caso, Visual Studio 2013, tal y como se muestra en las imágenes a continuación.

1

 

Una vez hayamos seleccionado la plantilla de Silverlight Application, lo siguiente que se nos consulta es si queremos incrustar el proyecto dentro de una aplicación web. En el ejemplo que expongo, lo incrustaré dentro de una aplicación web ASP.NET MVC, con lo que marcaré la opción y asignaré el nombre de mi aplicación web.

2

 

Por último, voy a añadir un control de tipo Label, que ubico centrado dentro del grid principal “LayoutRoot”, al que posteriormente “bindearé” con el texto localizado.

3

 

Si ejecutamos la solución, podremos comprobar cómo se abre el navegador, con un control Silverlight incrustado que contiene el label con el texto que hayamos especificado, en mi caso “Text to localize”

4

 

Añadiendo los ficheros de recursos localizados

El siguiente paso, será añadir los ficheros de recursos. Por simplicidad voy a crear sólo el fichero principal en inglés (LocalizedStrings.resx) y el fichero localizado en español (LocalizedStrings.es-ES.resx).

Para ello, he creado una carpeta que llamo “Resources” donde agregaré ambos ficheros de recursos.

resourcefiles

 

Ahora añadimos una nueva entrada dentro del fichero de recursos, “LabelLocalized” donde pondremos el texto deseado. Esto hay que hacerlo dentro de cada uno de los ficheros de recursos y tendremos tantos como lenguas en las que queramos localizar nuestra aplicación. Para facilitar esta labor, existen “plugins” que nos pueden ayudar, pero de esto hablaremos otro día.

5

 

Localizando el contenido dentro del código XAML

Bien, ahora ya tenemos el control en código XAML que queremos localizar en nuestra interfaz y el texto que queremos que aparezca, por lo que el siguiente paso será enlazar ambos “bindeando” el control Label con la entrada del fichero de recursos.

Lo primero será crear una clase, que llamaré “Localizer.cs” que se encargará de varios cometidos:

  1. Determinar la cultura que vamos a usar
  2. Determinar el fichero en el que se encuentran las entradas localizadas
  3. Servir de interlocutor/pasarela entre nuestra interfaz y los ficheros de recursos para abstraernos de los mismos
    public class Localizer
    {
        public Localizer()
        {
            Culture = Thread.CurrentThread.CurrentUICulture;
            Language = XmlLanguage.GetLanguage(_culture.Name);
            resource = new SilverlightLocalization.Resources.LocalizedStrings();
        }
 
        private static SilverlightLocalization.Resources.LocalizedStrings resource ;
 
        public SilverlightLocalization.Resources.LocalizedStrings Resource { get { return resource; } }
 
        XmlLanguage _language;
        public XmlLanguage Language
        {
            get { return _language; }
            private set { _language = value; RaiseOnPropertyChanged("Language"); }
        }
 
        CultureInfo _culture;
        public CultureInfo Culture
        {
            get { return _culture; }
            set
            {
                //Contract.Requires(value != null);
 
                if (_culture == value) 
                    return;
                _culture = value;
 
                Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = value;
                Language = XmlLanguage.GetLanguage(value.Name);
 
                RaiseOnPropertyChanged("Culture");
            }
        }
 
        protected void RaiseOnPropertyChanged(string propName)
        {
            var e = OnPropertyChanged;
            if (e != null) e(this, new PropertyChangedEventArgs(propName));
        }
 
        public event PropertyChangedEventHandler OnPropertyChanged;
    }

 

El siguiente paso, será asignar un alias a nuestro localizador para que la interfaz sepa interpretarlo y, para ello, editamos el fichero “App.xaml” añadiendo el correspondiente código dentro de los recursos de la aplicación.

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             x:Class="SilverlightLocalization.App"
             >
    <Application.Resources>
        <resources:Localizer xmlns:resources="clr-namespace:SilverlightLocalization.Resources" 
                             x:Key="LocalizedStrings"/>
    </Application.Resources>
</Application>

 

Ahora que ya podemos usar el localizador para comunicar nuestra interfaz con los ficheros de recursos, vamos a establecer el Binding del valor en el control Label dentro del código XAML, para lo que deberíamos tener un código tal que así:

        <sdk:Label HorizontalAlignment="Center" 
                   Height="28" 
                   VerticalAlignment="Center" 
                   Content="{Binding Path=Resource.LabelLocalized, 
                                     Source={StaticResource LocalizedStrings}}"/>

 

Con esto, en principio ya deberíamos poder ver nuestro texto localizado, pero esperad que aún hay más.

 

Localizando el contenido dentro del código C#

Antes de continuar, podría ser que quisiéramos localizar el texto desde nuestro código C# (yo recomiendo que en la medida de lo posible se haga desde la propia vista en el caso de controles con un valor fijo), así que tenemos una vía alternativa, para la que no necesitamos la clase que hace de localizador, sino que simplemente haríamos uso de un ResourceManager que nos permite acceder a las entradas de los ficheros de recursos de una forma sencilla.

ResourceManager rm = null;
rm = new ResourceManager("SilverlightLocalization.Resources", Assembly.GetExecutingAssembly());
 
string localizedValue = rm.GetString("LabelLocalized");

 

Una vez hecho esto, podemos asignar el valor a cualquier control XAML que nos lo permita.

 

¿Por qué sigo sin ver cambios? Realizando los últimos ajustes

Una vez tengamos todo esto, pensaremos que está el trabajo realizado, así que si ejecutamos la aplicación…

4

 

No ha cambiado nada, ¿Por qué? <ironic mode=”ON”> Por extraño que parezca… en Silverlight las cosas no suelen ser tan fáciles como deberían </ironic> así que, localizar una aplicación Silverlight no iba a ser coser y cantar, o sí, pero al menos no iba a ser intuitivo.

¿Qué es lo que nos falta? Bien, pues nos falta, indicar a la aplicación Silverlight que puede usar las culturas en las que queremos que se localice. Esto lo haremos editando el fichero del proyecto, en el ejemplo “SilverlightLocalization.csproj” que no es más que un fichero XML y, en el nodo SupportedCultures, debemos añadir, separadas por “;”, todas las culturas que queramos tal y como muestro en la imagen.

6

 

9

 

Una vez hayamos añadido las culturas, podremos observar cómo nuestra aplicación muestra el valor correspondiente a la cultura.

 

Conclusiones

Con Silverlight las tareas a priori sencillas se pueden convertir en algo un poco “duro” de completar.

Para más referencias, podéis leeros a fondo este artículo de la MSDN donde se explica, aunque de forma algo enrevesada y desorganizada cómo funciona la localización en Silverlight.

 

Código de ejemplo

Podéis descargaros el código de ejemplo de aquí.

download-code