Cargar un Hashtable en un control de lista en ASP.NET
Si programas aplicaciones en ASP.NET o estás desarrollando un simple formulario para recopilar datos de los usuarios, una de las cosas que seguramente necesitarás es rellenar una lista o un desplegable con los datos provenientes de un Hashtable, o algún otro tipo de colección. Con .NET esto es realmente sencillo pero si nunca lo has hecho antes quizás tu primera idea sea recorrer la colección de elementos e ir añadiéndolos uno a uno a la lista.
Todos los controles de lista tanto de Winforms como de Webforms disponen de una propiedad llamada DataSource que permite asignar una colección de elementos al control. Centrándonos en los controles Web, puede ser suficiente con asignar la colección de elementos al control de lista y llamar a su método DataBind
. Este método es el que se encarga de recorrer la colección y para cada elemento obtener la información con la que genera los distintos elementos del listado.
Para rellenar los campos de valor y de texto del listado, DataBind llama automáticamente al método «ToString» de cada elemento de la colección, aunque esto no puede ser siempre conveniente. Así por ejemplo, si queremos rellenar un desplegable con los valores de un Hashtable, resultaría que obtendríamos una lista rellenada con System.Collections.DictionaryEntry
, puesto que este es el tipo de los elementos almacenados en un Hashtable. En el caso de que tuviéramos un ArrayList en que almacenásemos objetos de la clase «Punto», obtendríamos en este caso el nombre completo de la clase «Punto», a no ser que hayamos sobrecargado el método ToString, que es al que se llama por defecto para obtener la información de texto y valor con la que se construye la lista, y que por defecto, devuelve una cadena con el nombre de la clase. Por lo tanto una posible opción es sobrecargar el método ToString de los elementos almacenados, pero esto no siempre es posible, por ejemplo para el Hashtable, ya que siempre almacena sus elementos utilizando «DirectoryEntry». Además seguiríamos teniendo otro problema y es que estamos utilizando el método ToString tanto para el texto como para el valor de los elementos del listado, pero normalmente es necesario que sean diferentes.
Para resolver esta situación los controles de listado disponen de dos propiedades que permiten indicar el nombre de las propiedades que hay que pedir a los elementos de la colección, tanto para el valor como para el texto. Así por ejemplo utilizaríamos DataTextField
para indicar la propiedad con la información de texto y DataValueField
para el valor de cada elemento.
A continuación se muestra un ejemplo con el que se rellena un desplegable con una serie de datos que previamente cargamos en un Hashtable. Esto no es lo más habitual ya que normalmente utilizaremos nuestras propios tipos de colección, o ArrayLists por ejemplo, pero la idea es la misma para cualquier otro tipo de colección.
Independientemente del tipo de colección y los elementos que almacenemos en ella, el funcionamiento es igual, siendo únicamente necesario modificar los nombres de las propiedades para que de amolden al tipo de los elementos almacenados en la colección.
<%@ Page language="c#" %> <%@ import Namespace="System.Collections" %> <script runat="server"> public void Page_Load(Object sender, EventArgs e) { Hashtable datos = new Hashtable(); datos.Add(1, "Lucas"); datos.Add(5, "Mario"); datos.Add(9, "Alberto"); lbDatos.DataSource = datos; lbDatos.DataTextField = "Value"; lbDatos.DataValueField = "Key"; lbDatos.DataBind(); } </script> <html> <head> <title></title> </head> <body> <form runat="Server"> <asp:ListBox id="lbDatos" runat="Server" size="1" /> </form> </body> </html> |
Si, pero
Me parece cojonudo pero no funciona si lo haces con webcontrols en el codebehind , o por lo menos con el Dropdownlist. Aviso porque vi en mil sitios este ejemplo pero parece que la peña se mono pasa un poco del codebehind y lo de los scripts en la .aspx es realmente incomodo cuando hay algún método más que page_load, yo en mis controles de usuario tengo 5 metodo mínimo y meterlos en un script como que no. Además es feo,feo,feo lo de los scripts, feo.
el funcionamiento en codebehind debería ser igual, yo también estoy contigo en que lo de mezclar código y maquetación no es muy buena idea, queda todo mucho mejor con codebehind, otra cosas es que lo compiles en DLL o no, yo prefiero compilación al vuelo normalmente. El problema que tienes puede deberse al DropDownList, me suena que alguna vez me ha dado problemas y creo recordar que tuve que cargar la lista «manualmente», aunque no te lo puedo confirmar.
el problema es con los webcontrols, con los listcontrols en concreto, hay un método por ahí sin
implementar, «pues ya sabes chaval, a colaborar» direis alguno, pero por el momento no tengo tiempo.Por otro lado, tampoco veo esencial el uso del databinding, con un foreach te lo puedes montar perfectamente
y no caes en la tentación de llevarte el módelo a la vista, que los antipatrones que propone MS me hacen rechinar los dientes. O proponían, que para las últimas versiones de la PetStore.Net parece que contrataron
mejores copiadores de J2EE. Aviso: no me hagais mucho caso.