Regionalizar aplicaciones Silverlight

Voy a mostrar como podemos hacer que nuestra aplicación Silverlight este regionalizada. Esta propiedad es muy importante para aquellos que desarrollan aplicaciones que pueden ser utilizadas por personas de diferentes países, ya que puede cambiar no sólo el idioma sino también la forma de mostrar una fecha o un importe.

La idea es la misma que en una aplicación Web, utilizando archivos resx (Resources), la diferencia es que hay pequeños trucos que debemos realizar para que funcione, ya que haciendo los pasos normales nos vamos a encontrar con algunos errores de implementación.

AGREGAR RESOURCES

El primer paso es desde nuestra aplicación Silverlight, agregar un nuevo ítem, del tipo Resources File.

1Luego, vamos a ir agregando un resource por cada cultura que queremos regionalizar. Para este ejemplo serían Page.xaml.resx (por defecto), Page.xaml.fr.resx (para cultura francesa) y Page.xaml.en.resx (para cultura inglesa).

Vamos a agregar un item Texto y otro Imagen, donde vamos a colocar que queremos mostrar según la cultura.

Vamos al primer truco. Si nosotros vamos a acceder a cualquier resource, nos va a tirar error o no va a funcionar. Esto se debe a que por defecto, los resources que agregamos están definidos para uso Interno, y deberían estar para uso Público.

2 Modificamos para cada archivo, el modo de acceso, y lo ponemos en Public.

2b Además debemos modificar el constructor del resource, y definirlo como public.

Importante: Deben modificar el constructor cada vez que modifiquen un valor del resource, ya que Visual Studio lo vuelve a generar.

CONFIGURAR APLICACIÓN

Otro truco, que debemos realizar antes de seguir con la implementación, es definir en la aplicación que culturas vamos a aceptar. Para ello debemos abrir con Notepad el archivo de proyecto nuestra aplicación y modificar el tag SupportedCultures y agregar las culturas que vamos a aceptar.

3 

ENLACE DE DATOS 

Vamos a referenciar a los resources dentro de nuestra aplicación. 

En Page.xaml, primero vamos a referenciar a la clase.

xmlns:Res="clr-namespace:LocalizationApp.Resources"

Ahora agregamos el control resource para poder utilizarlo con los controles de nuestra aplicación.

<UserControl.Resources>
    <Res:Page_xaml x:Name="PageResource" />
</UserControl.Resources>

Ahora vamos a agregar controles para mostrar texto, la bandera de la cultura que estamos visualizando y un combo para cambiar de cultura en línea.

<StackPanel Orientation="Vertical">
 
    <TextBlock x:Name="textCultura" 
               Text="{Binding Texto}" 
               Width="100" />
    
    <Image x:Name="imagenCultura" Width="16" Height="11" />
 
    <ComboBox x:Name="comboCultura" 
              Width="120" Margin="1"
              SelectionChanged="comboCultura_SelectionChanged">
        <ComboBoxItem Tag="es" Content="Español" />
        <ComboBoxItem Tag="en" Content="Inglés" />
        <ComboBoxItem Tag="fr" Content="Francés" />                
    </ComboBox>
    
</StackPanel>

Vemos que al TextBlock lo estamos enlazando con la propiedad Texto del resource, por lo que al entrar a la aplicación va a buscar según la cultura que tenga, el valor correspondiente.

Vamos al code-behind.

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    System.Globalization.CultureInfo cultureInfo = 
            System.Globalization.CultureInfo.CurrentUICulture;
    string cultureName = cultureInfo.Name.ToLower();
                
    foreach (ComboBoxItem item in comboCultura.Items)
    {
        string tag = item.Tag.ToString();
        if (cultureName.Equals(item.Tag))
            comboCultura.SelectedItem = item;                
    }
    if (comboCultura.SelectedIndex < 0)
        comboCultura.SelectedIndex = 0;
 
    CulturaUpdate();
}

Desde el load de la aplicación, vamos a asignarle el valor al combo de culturas, además vamos a actualizar por código la imágen según el valor del resource.

private void CulturaUpdate()
{
    this.DataContext = new Page_xaml();
 
    string bandera = Page_xaml.Imagen;
 
    Uri uriImage = 
        new Uri(string.Format("imagenes/{0}", bandera), UriKind.Relative);
    Stream objImageStream = Application.GetResourceStream(uriImage).Stream;
    BitmapImage objBI = new BitmapImage();
    objBI.SetSource(objImageStream);
    imagenCultura.Source = objBI;                          
}

Esta es la función que actualiza la imágen, buscando en el resource el valor correspondiente.

ACTUALIZAR CULTURA DESDE CÓDIGO

private void comboCultura_SelectionChanged(object sender, 
                                           SelectionChangedEventArgs e)
{
    if (comboCultura != null)
    {
        if (0 <= comboCultura.SelectedIndex)
        {
            ComboBoxItem item = comboCultura.SelectedItem as ComboBoxItem;
            System.Threading.Thread.CurrentThread.CurrentUICulture = 
                    new System.Globalization.CultureInfo(item.Tag.ToString());
            CulturaUpdate();
        }
    }
}
 

Ahora la función que permite cambiar la regionalización. Vemos que debemos crear un nuevo CultureInfo según el valor seleccionado.

PARAMETRO DE CULTURA EN OBJETO SILVERLIGHT  

Ahora vamos a ver de que manera podemos llamar a nuestra aplicación con la cultura que nosotros queramos.

<param name="UICulture" value="fr" />

Al crear el objeto Silverlight, podemos pasarle un parámetro para saber que cultura vamos a querer, en lugar de la que pusimos por defecto.

De esta manera regionalizamos nuestra aplicación, permitiendo tener soporte para varias culturas.

Pueden descarga el ejemplo de la aplicación aquí.

No Comments