Localización.

Podemos definir la localización como la propiedad de una aplicación de hacer frente a todos aquellos procesos de traducción de los distintos recursos para una cultura especifica. Para definirlo más claramente, estaríamos hablando de la posibilidad de ofrecer funcionalidad multiidioma en la aplicación. La localización no debe confundirse con la globalización, ya que ésta última hace referencia a todas aquellas acciones relacionadas con el desarrollo de aplicaciones que se adapten a culturas diferentes.

Así pues, si quieres construir aplicaciones verdaderamente atractivas a la hora de su comercialización, tendrás que tener en cuenta la posibilidad de que puedan ofrecer una visualización adaptada a dos o más idiomas. Hoy en día, debido a la amplitud de alcance de Internet, es fundamental esta característica en cualquier aplicación destinada a una comercialización amplia.

Antes de entrar en materia, podríamos resumir el proceso en dos áreas: un conjunto de recursos que almacenarán las cadenas de texto en los diferences idiomas aplicables, y un proceso dentro de la aplicación que será el encargado del cambio del idioma en tiempo de ejecución. Yo voy a enseñarte un modo de hacerlo por el cual el cambio del idioma se hace de manera automática en tiempo de ejecución sin ser necesario que, para el cambio del idioma, la aplicación tenga que reiniciarse.

Sobre la solución de prueba sobre la que has estado trabajando en todos los temas anteriores, deberás añadir un nuevo proyecto de tipo 'WPF User Control Library' llamado, por ejemplo, 'Languages'. En este proyecto almacenaremos los recursos necesarios para contener las cadenas de texto en diferences idiomas. Agrega una clase llamada 'Culture' en un nuevo archivo llamado 'Culture.cs':

public static class Culture
{
    public static string ModifiedCulture
    {
        get;
        set;
    }
    public static ResourceDictionary SetLanguage()
    {
        var resourceDictionary = new ResourceDictionary();
        switch(ModifiedCulture)
        {
            case "en-GB":
                resourceDictionary.Source = new Uri(@"/Languages;component/languages\language.en-US.xaml", UriKind.Relative);
                break;
            case "es-ES":
                resourceDictionary.Source = new Uri(@"/Languages;component/languages\language.es-ES.xaml", UriKind.Relative);
                break;
            default:
                resourceDictionary.Source = new Uri(@"/Languages;component/languages\language.es-ES.xaml", UriKind.Relative);
                break;
        }
        return resourceDictionary;
    }
}

Hemos definido una propiedad llamada 'ModifiedCulture' que se utilizará para leer y establecer el lenguage seleccionado. Además, hemos establecido un procedimiento para establecer el diccionario de recursos requerido para cada lenguage, representado en dos arvhivos distintos, 'language.en-GB.xaml' y 'language.es-ES.xaml', para el inglés y el español, respectivamente. Así pues, debemos crear también esos dos archivos, agregando una carpeta llamada 'languages' y dentro de ella dos archivos de diccionario de recursos.

Uno para el español:

<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">
    <system:String x:Key="CadenaTextoMultiidioma">Español</system:String>
</ResourceDictionary>

Y otro para el inglés:

<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">
    <system:String x:Key="CadenaTextoMultiidioma">Inglés</system:String>
</ResourceDictionary>

Comoves, son dos archivos exactamente iguales excepto en que la cadena de texto varía según el idioma. Sin embargo, la clave 'CadenaTextoMultiidioma' se mantiene en los dos archivos, pues será la clave a la que hagamos referencia en el control de la ventana para que tomer su valor de estos archivos según el idioma.

Ahora tendremos que irnos a nuestra ventana principal y creat, por ejemplo, una etiqueta:

<Label Content="{DynamicResource ResourceKey=CadenaTextoMultiidioma}"/>

Evidentemente, para enlazar la clave 'CadenaTextoMultiidioma' con el archivo de recursos, es necesario que establezcas en la ventana principal dónde se encuentran los recursos:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/Languages;component/languages/language.en-GB.xaml"/>
            <ResourceDictionary Source="pack://application:,,,/Languages;component/languages/language.es-ES.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

Hemos indicado que los archivos de recursos se encuentran en el ensamblado 'Languages', y más concretamente en la carpeta 'languages'. De esta manera, WPF se dirigirá automáticamente al archivo 'Languages.dll' resultante de la compilación de la solución, 'dll' que se encontrará junto al 'exe' ejecutable de nuestra aplicación.

Finalmente, lo oúnico que nos hace falta es un par de controles, por ejemplo dos botones, que actuarán a modo de cambio del idioma. Creo que no es necesario que también te dé el código XAML de dos botones; si fuera necesario entonces creo que deberías ir unos cuantos temas más atras. En los eventos 'Click' de cada uno, adjunta el siguiente código C#, que será el encargado del cambio de idioma automático.

Para el español:

Culture.ModifiedCulture = "es-ES";
Resources.MergedDictionaries.Add(Culture.SetLanguage());

Para el inglés:

Culture.ModifiedCulture = "en-GB";
Resources.MergedDictionaries.Add(Culture.SetLanguage());

Sólo queda compilar y comprobar que, según el botón pulsado, el contenido de la etiqueta cambiará a un idioma u otro en tiempo de ejecución y de manera inmediata.

Sólo hemos incluido una clave en los archivos de recursos. Sin embargo, la idea es que haya una clave por todas y cada una de las cadenas de texto que haya en la aplicación, tanto en los controles como en mensajes de la aplicación. De esta manera, incluiríamos decenas de claves en los archivos de recursos de tal manera que todo el texto de la aplicación estaría contenido en los diccionarios de recursos de los idiomas.