Cómo usar la localización en C #

Simplemente no puedo hacer que la localización funcione.

Tengo una biblioteca de clase. Ahora quiero crear archivos de resx allí, y devolver algunos valores basados ​​en el cultivo de hilos.

¿Cómo puedo hacer eso?

  • Agregue un archivo de recursos a su proyecto (puede llamarlo “strings.resx”) haciendo lo siguiente:
    Haga clic con el botón derecho en Propiedades en el proyecto, seleccione Agregar -> Nuevo elemento … en el menú contextual, luego en la lista de elementos de Visual C # seleccione “Archivo de recursos” y strings.resx nombre strings.resx .
  • Agregue un recurso de cadena en el archivo resx y asígnele un buen nombre (ejemplo: asígnele el nombre “Hola” y asígnele el valor “Hola”)
  • Guarde el archivo de recursos ( nota: este será el archivo de recursos predeterminado , ya que no tiene un código de idioma de dos letras)
  • Agregue referencias a su progtwig: System.Threading y System.Globalization

Ejecute este código:

 Console.WriteLine(Properties.strings.Hello); 

Debería imprimir “Hola”.

Ahora, agregue un nuevo archivo de recursos, llamado “strings.fr.resx” (observe la parte “fr”; esta contendrá recursos en francés). Agregue un recurso de cadena con el mismo nombre que en strings.resx, pero con el valor en francés (Name = “Hello”, Value = “Salut”). Ahora, si ejecuta el siguiente código, debe imprimir Salut:

 Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR"); Console.WriteLine(Properties.strings.Hello); 

Lo que sucede es que el sistema buscará un recurso para “fr-FR”. No encontrará uno (ya que especificamos “fr” en su archivo “). Luego volverá a buscar” fr “, que encuentra (y usa).

El siguiente código, imprimirá “Hola”:

 Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US"); Console.WriteLine(Properties.strings.Hello); 

Esto se debe a que no encuentra ningún recurso “en EE. UU.” Ni ningún recurso “en”, por lo que volverá al valor predeterminado, que es el que agregamos desde el principio.

Si es necesario, puede crear archivos con recursos más específicos (por ejemplo, strings.fr-FR.resx y strings.fr-CA.resx para francés en Francia y Canadá, respectivamente). En cada archivo, deberá agregar los recursos para esas cadenas que difieren del recurso al que recurriría. Por lo tanto, si un texto es el mismo en Francia y Canadá, puede ponerlo en strings.fr.resx, mientras que las cadenas que son diferentes en francés canadiense podrían entrar en strings.fr-CA.resx.

Es bastante simple, en realidad. Cree un nuevo archivo de recursos, por ejemplo Strings.resx . Establezca el Access Modifier en Public . Utilice la plantilla de archivo correspondiente, de modo que Visual Studio generará automáticamente una clase de acceso (el nombre será Strings , en este caso). Este es tu idioma predeterminado

Ahora, cuando desee agregar, por ejemplo, localización alemana, agregue un archivo resx localizado. Esto será típicamente Strings.de.resx en este caso. Si desea agregar una localización adicional para, por ejemplo, Austria, también creará un Strings.de-AT.resx .

Ahora ve a crear una cadena, digamos una cadena con el nombre HelloWorld . En su Strings.resx , agregue esta cadena con el valor “¡Hola, mundo!”. En Strings.de.resx , agrega “Hallo, Welt!”. Y en Strings.de-AT.resx , agrega “Servus, Welt!”. Eso es todo hasta ahora.

Ahora tiene esta clase de Strings generada, y tiene una propiedad con un getter HelloWorld . Obtener esta propiedad cargará “Servus, Welt!” cuando su configuración regional es de-AT, “Hallo, Welt! cuando su configuración regional es cualquier otra configuración regional (incluidos DE-DE y de-CH), y” Hello, World! “cuando su configuración regional es cualquier otra cosa. Si se trata de una cadena faltando en la versión localizada, el administrador de recursos subirá automáticamente la cadena, desde el recurso más especializado al invariante.

Puede usar la clase ResourceManager para tener más control sobre cómo exactamente está cargando cosas. La clase Strings generada lo usa también.

Gran respuesta de F.Mörk. Pero si quiere actualizar la traducción o agregar nuevos lenguajes una vez que se lanza la aplicación, está atascado, porque siempre debe recomstackrlo para generar resources.dll.

Aquí hay una solución para comstackr manualmente un dll de recursos. Utiliza las herramientas resgen.exe y al.exe (instaladas con el SDK).

Digamos que tiene un archivo de recursos Strings.fr.resx, puede comstackr un archivo DLL de recursos con el siguiente lote:

 resgen.exe /compile Strings.fr.resx,WpfRibbonApplication1.Strings.fr.resources Al.exe /t:lib /embed:WpfRibbonApplication1.Strings.fr.resources /culture:"fr" /out:"WpfRibbonApplication1.resources.dll" del WpfRibbonApplication1.Strings.fr.resources pause 

Asegúrese de mantener el espacio de nombres original en los nombres de los archivos (aquí “WpfRibbonApplication1”)

Además, la gran respuesta de @Fredrik Mörk en cadenas para agregar localización a un formulario hace lo siguiente:

  • Establezca la propiedad del formulario "Localizable" en true
  • Cambie la propiedad de Language del formulario al idioma que desee (a partir de un menú desplegable agradable con todos)
  • Traduce los controles en esa forma y muévelos si es necesario (aplasta esas oraciones francesas realmente largas).

Este artículo de MSDN sobre Localizing Windows Forms brinda más información sobre él.

Una solución y la elaboración de la respuesta @Fredrik Mörk .

  • Agregue un archivo de recursos Strings.resx a su proyecto (o un nombre de archivo diferente)
  • Establezca el Access Modifier en Public (en la pestaña del archivo abierto Strings.resx )
  • Agregue un recurso de cadena en el archivo resx: (ejemplo: nombre Hello , valor Hello )
  • Guarde el archivo de recursos

Visual Studio autogenera una clase respectiva de Strings , que en realidad se coloca en Strings.Designer.cs . La clase está en el mismo espacio de nombres del que esperaría que se coloque un archivo .cs recién creado.

Este código siempre imprime Hello , porque este es el recurso predeterminado y no hay recursos específicos del idioma disponibles:

 Console.WriteLine(Strings.Hello); 

Ahora agregue un nuevo recurso específico del idioma:

  • Agregar Strings.fr.resx (para francés)
  • Agregue una cadena con el mismo nombre que anteriormente, pero con un valor diferente: (nombre Hello , valor Salut )

El siguiente código imprime Salut :

 Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR"); Console.WriteLine(Strings.Hello); 

Qué recurso se utiliza depende de Thread.CurrentThread.CurrentUICulture . Se configura según la configuración de idioma de la interfaz de usuario de Windows o se puede configurar manualmente como en este ejemplo. Aprenda más sobre esto aquí .

Puede agregar recursos específicos del país como Strings.fr-FR.resx o Strings.fr-CA.resx .

La cadena que se utilizará se determina en este orden de prioridad:

  • De un recurso específico del país como Strings.fr-CA.resx
  • Del recurso específico del lenguaje como Strings.fr.resx
  • De Strings.resx predeterminado

Tenga en cuenta que los recursos específicos del idioma generan ensambles satelitales .

También aprenda cómo CurrentCulture difiere de CurrentUICulture aquí .

Además de la respuesta de @Eric Bole-Feysot :

Gracias a los ensamblados de satélites, la localización se puede crear en base a los archivos .dll / .exe . De esta manera:

  • el código fuente (proyecto VS) podría separarse del proyecto de lenguaje,
  • agregar un nuevo idioma no requiere recomstackr el proyecto,
  • la traducción podría hacerse incluso por el usuario final.

Existe una herramienta poco conocida llamada LSACreator (gratuita para uso no comercial o opción de compra) que le permite crear una localización basada en archivos .dll / .exe. De hecho, internamente (en el directorio del proyecto de idioma) crea / administra las versiones localizadas de los archivos de resx y comstack un ensamblado de forma similar a la descrita por @Eric Bole-Feysot .

En mi caso

 [assembly: System.Resources.NeutralResourcesLanguage("ru-RU")] 

en AssemblyInfo.cs evitó que todo funcionara como siempre.