Como llenar un DropDownList con el listado de nombres de paises usando las clases de ASP.NET

Fecha: 01/Feb/2005 (30 Enero 2005)
Autor: Jose Alfredo García Guirado. email: jagg@g-softsolutions.de

 


Introducción

El uso de listas de paises es común en formularios. Entrar los lista manualmente es costoso en tiempo y propenso a errores. El artículo muestra la forma de llenar un DropdownList con la lista de paises usando la información que posee el Net Framework 1.1.

Contenido

SECCION I- Clases necesarias para obtener la información de nombres de paises en el Net Framework.

SECCION II- Limitaciones que tiene el uso de esta solución

SECCION III- Discusión del código de ejemplo

Conclusiones

SECCION I : Clases necesarias para obtener la información de nombres de paises en el Net Framework

El Framework 1.1 contiene en la unidad System.Globalization las clases que vamos a usar: RegionInfo y CultureInfo.

La clase RegionInfo está pensada, para poder conocer, dado el código de dos letras del país (según ISO-3166), una serie de características sobre el país en cuestión, incluyendo el nombre del mismo. A continuación se listan las propiedades más interesantes de dicha clase para nuestro trabajo:

 Propiedades  Descripción
 DisplayName  Obtiene el nombre del país en el lenguaje localizado del Net Framework instalado en su PC. Es decir si su Net Framework esta en español el nombre del país será entragado en español.
 English Name  El nombre del país SIEMPRE es devuelto en Ingles

La clase también tiene otras propiedades interesantes como el signo de la moneda de cada país etc.

La dificultad para usar esta clase en la operación que nos trata, es que solo se puede invocar utilizando un elemento de por vez. El constructor de esta clase admite dos versiones sobrecargadas.

1.- Por un parámetro int que representa el código de identificación del país.

2.- Por el código de dos letras ISO 3166 que representa el código de identificación.

Usar uno de estos sistemas implicaria sustituir el trabajo de crear una lista de nombres de paises por una lista de identificadores de paises, y no lograríamos mucho avanze en nuestros objetivos. En nuestra ayuda viene la clase CultureInfo Esta clase contiene la información sobre el idioma que se habla en cada país o región, codificado mayormente según la RFC 1766 (el conocido formato de 4 letras separadas por un guión) . Además de dicha información esta clase es muy interesante para nuestro trabajo por dos razones:

1.- Es una colección de clases. Es decir se puede tratar todas las CultureInfo posibles dentro de una colección.

2.- Posee un método que devuelve para cada CultureInfo individual el identificador “integer” de la región. Esta propiedad se llama LCID. El valor de dicha propiedad puede ser usado como parámetro para iniciar una clase RegionInfo.

Es decir el algoritmo general simplificado para obtener los los nombres puede resumirse como:

1.- Crear un arreglo de CultureInfo[] con la información de todas las culturas contenidas en el Framework.

2.- Recorrer uno a uno este arreglo obteniendo el LCID de cada CultureInfo.

3.- Con el LCID obtenido inicializar una clase RegionInfo y ontener por la propiedad de DisplayName o EnglishName el nombre del país.

4.- Cargar el valor en el DropDownList

Sencillo verdad, pero esto tiene sus limitaciones .... que vamos a ver en la siguiente sección antes de discutir el código en su generalidad.

SECCION II- Limitaciones que tiene el uso de esta solución

Existen varias limitaciones a tener en cuenta al hacer el código para obtener nuestro DropdownList con el listado de los paises.

1.- La colección de CultureInfo, se refiere a culturas no a paises, por lo que pueda ser dos objetos de la colección devuelvan un mismo país. Esto provocaría paises repetidos en nuestra lista.

2.- Puede ser que el LCID devuelto no coincida con ningún país definido en RegionInfo, en este caso se producirá una excepción en nuestro código. Esta situación se motiva entre otras cosas porque el Framework no posee en RegionInfo un listado de todos los paises posibles, mientras que CultureInfo, si tiene la información de todas las culturas.

3.- La limitación más fuerte, solo existe un listado de 110 paises, esto puede ser suficiente para la mayoría de los casos, pero existen algunas ausencias notorias como son Afgahnistan y Cuba.

Para eliminar la limitación de los puntos 1 y 2, nuestro código tiene que contemplar: la eliminación de los paises repetidos y un mecanismo para controlar la excepción por código no encontrado.

SECCION III- Discusión del código de ejemplo.

El código que utilizamos para este ejemplo, almacenará en un DropdownList el listado de nombres de paises en el Text del control y el código de identificación de dos letras ISO3166 en la propiedad Value del mismo. Veamos primero el ejemplo en su conjunto. El mismo va a estar en el evento onload de la página:

 
private void Page_Load(object sender, System.EventArgs e)
{
   if (IsPostBack == false)
   {
        RegionInfo    reginfo;                            //Definiendo un objeto RegionInfo    
        //Creando una lista de todas las culturas.....
         CultureInfo[] cultInfoList    =  CultureInfo.GetCultures(CultureTypes.AllCultures);
        //Explorando todas las culturas (no todas retornan paises que se encuentran en RegionInfo            
        foreach (CultureInfo cultInfo in cultInfoList)
        {
	           //Se puede generar una excepción por no corresponder un culture info LCID con 
            //un un código existente en RegInfo (por ejemplo Cuba) en ese caso se captura 
            //la excepción y continua el lazo
            try
            {
               //Crear una clase reginfo para traer los nombres del país
               reginfo = new RegionInfo(cultInfo.LCID);                //Se crea una reg info del pais
               //Crear un ListItem para almacenar el nombre del país y el código de dos letras ISO 
               ListItem li = new ListItem(reginfo.DisplayName, reginfo.TwoLetterISORegionName);
               //Debido a que diferentes culture info pueden generar diferentes varias veces el
               //mismo pais, verificar que el pais ya no se encuentre.
               if (DDL1.Items.IndexOf(li) < 1)                
               {DDL1.Items.Add(li);}                            
             }
             catch //Captura de la excepción por falta de correspondencia de código
             {
               ;
             }
          }
      }
 }

Ahora veamos el código paso a paso:

1.- Ubicación del código:


private void Page_Load(object sender, System.EventArgs e)
{
   if (IsPostBack == false)
   {

Observe que el código se situa en el evento de carga de la página pero, en su totalidad se ejecuta cuando IsPostBack es false, es decir la primera vez que se carga la página, a partir de ahí los datos se almacenan en el StateView, junto con los cambios que haga el usuario en el control.

2.- Definiendo el RegionInfo y obteniendo la lista de Culturas
RegionInfo    reginfo;   //Definiendo un objeto RegionInfo    
//Creando una lista de todas las culturas.....
CultureInfo[] cultInfoList = CultureInfo.GetCultures(CultureTypes.AllCultures);

Se define un nombre para la clase RegionInfo, y en la segunda linea se define un arreglo de CultureInfo. RegionInfo no es instanciado en este momento. Observe además como se obtiene la lista de todas las culturas usando el método: CultureInfo.GetCultures(CultureTypes.AllCultures);

3.- El lazo principal de iteración de todas las culturas
 
   foreach (CultureInfo cultInfo in cultInfoList)
        {
	           //Se puede generar una excepción por no corresponder un culture info LCID con 
            //un un código existente en RegInfo (por ejemplo Cuba) en ese caso se captura 
            //la excepción y continua el lazo
            try
            {
               //Crear una clase reginfo para traer los nombres del país
               reginfo = new RegionInfo(cultInfo.LCID);                //Se crea una reg info del pais
               //Crear un ListItem para almacenar el nombre del país y el código de dos letras ISO 
               ListItem li = new ListItem(reginfo.DisplayName, reginfo.TwoLetterISORegionName);
               //Debido a que diferentes culture info pueden generar diferentes varias veces el
               //mismo pais, verificar que el pais ya no se encuentre.
               if (DDL1.Items.IndexOf(li) < 1)                
               {DDL1.Items.Add(li);}                            
             }
             catch //Captura de la excepción por falta de correspondencia de código
             {
               ;
             }
          }
        }

El código itera mediante el foreach a traves de toda la colección de CultureInfo. Para protegerse de la limitación de que no todas las CultureInfo devuelven un LCID válido para RegionInfo, se introduce el bloque try ... catch.. que captura de excepción generada, permitiendo que continue el proceso de iteración.

4.- Código dentro del lazo de iteración que puebla el DropDownList con los nombres de paises.
 
      //Crear una clase reginfo para traer los nombres del país
      reginfo = new RegionInfo(cultInfo.LCID);                //Se crea una reg info del pais
      //Crear un ListItem para almacenar el nombre del país y el código de dos letras ISO 
      ListItem li = new ListItem(reginfo.DisplayName, reginfo.TwoLetterISORegionName);
      //Debido a que diferentes culture info pueden generar diferentes varias veces el
      //mismo pais, verificar que el pais ya no se encuentre.
      if (DDL1.Items.IndexOf(li) < 1)                
      {DDL1.Items.Add(li);}   

En cada iteración es creado un RegionInfo con el código LCID retornado por CultureInfo.

La segunda linea coloca en un ListItem , creado al efecto, la información retornada de RegionInfo, en este ejemplo el nombre del país y el código ISO del mismo.

La tercera linea nos salvaguarda de entrar items repetidos a nuestro control, comparando si existe ya un item en el DropDownList que coincida con el nuevo creado. El método IndexOf retorna el indice de un item que coincida con su argumento dentro de la lista de items en el control.

Por último en la linea 4 es añadido el item al DropDownList. Un proyecto con el ejemplo en Visual Studio se encuentra adjunto a este artículo y puede verse el resultado del DropDownList.

Conclusiones

A quedado demostrado la posibilidad de usar la información almacenada en el Net framework 1.1 para llenar controles que trabajen con listas de paises. También se muestran los métodos para solsayar las limitaciones del procedimiento.

Queda pendiente el desarrollo de un algoritmo para añadir los paises faltantes, lo cual se sugiere que puede hacerse manualmente. El sistema se puede aplicar a otros controles de lista WEB y no WEB, así como para crear controles especializados con listas de características de paises como si poseen sistema métrico etc.

Se sugiere a los interesados en el tema a consultar la ayuda de NET para ver las propiedades asociadas a RegionInfo y CultureInfo.

Por último quisiera señalar para evitar confusiones, que las propiedades DisplayName y EnglishName en CultureInfo no pueden ser utilizadas para el fin aquí propuesto, porque no devuelven el nombre del país, como si hacen las propiedades homólogas en RegionInfo, sino el nombre del Idioma.  


Espacios de nombres usados en el código de este artículo:

System.Globalization;
System.Web.UI.WebControls;


ir al índice

Fichero con el código de ejemplo: jagg_DropDownConPaises.zip - 10 KB