Tutorial de ASP.NET
Vista Previa de ASP.NET 2.0

Datos Jerárquicos

Datos Jerárquicos

Los controles de fuente de datos pueden mostrar datos tanto jerárquicos como "tabular", o ambos. Los controles SqlDataSource y ObjectDataSource que se han mostrado antes son ejemplos de controles de fuente de datos tabulares. ASP.NET 2.0 también incluye dos controles de fuente de datos jerárquicos: XmlDataSource para conectarnos a ficheros XML y SiteMapDataSource para conectarnos a datos de navegación del site. Algunas técnicas para el uso de estos controles se muestran en los ejemplos que se verán a continuación.

Los Controles TreeView y Menu

De la misma forma que las fuentes de datos, los controles enlazados a datos también pueden ser jerárquicos. Mientras que un control tabular enlazado a datos representa una lista o una rejilla de datos, los controles jerárquicos enlazados a datos pueden moverse por una jerarquía de datos para representar los datos como relaciones padre-hijo en la UI. Dos ejemplos de controles enlazados a datos jerárquicos son TreeView y Menu de ASP.NET 2.0. Las tácnicas para enlazar estos controles a fuentes de datos jerárquicas se muestran en los ejemplos de esta sección.

Para más ejemplos de estos Controles acudid a las secciones TreeView y Menu de la sección de Referencia de Controles.

Enlazando a XML

El control XmlDataSource permite a los controles enlazar a datos XML. XmlDataSource tiene una propiedad DataFile para epecificar la ruta al fichero XML que se usará como entrada. También especificaremos la propiedad TranformFile para aplicar una transformación XSLT a los datos y la propiedad XPath para especificar un subconjunto de nodos que mostrará la fuente de datos.

El siguiente ejemplo muestra un control TreeView enlazado a un fichero XML mediante el control XmlDataSource. El TreeView asocia las propiedades de los objetos TreeNode individuales a los atributos de los nodos XML de la jerarquia (los atributos se "promocionan" a propiedades del objeto de datos por el bien del enlazado de datos). Por defecto, el control TreeView sólo representa los objetos de datos llamando a ToString() en el objeto. Ésto representa el nombre del elemento de nodo XML de forma que podemos ver la jerarquía de nodos a la que el TreeView está vinculado. Ésto no tiene que producir necesáriamente la representación deseada, pero nos da un punto de partida para ir personalizando la forma en que se representarán los datos.

C# Enlazando un TreeView a un Fichero XML


 
Para darle al TreeView una representación con mayor significado, podemos especificar enlazados de datos individuales para los nodos del árbol. Deberíamos añadir los objetos TreeNodeBinding a la colección de "Databindings" del TreeView para definir cómo se mapean los campos de datos jerárquicos a las propiedades TreeNode. Hay dos propiedades clave de TreeNodeBinding que determinan el conjunto de elementos de datos jerárquicos a los que se aplica el enlazado. La propiedad DataMember especifica el tipo de elementos de datos o, en el caso de datos XML, el nombre del elemento al que se aplica el enlazado. La propiedad Depth especifica la profundidad  dentro de los datos jerárquicos a la que se aplicará el enlazado de datos. Podemos establecer DataMember o Depth, o ambas. Por ejemplo, para definir los enlaces a datos para todos los elementos Book de un fichero XML, estableceremos DataMember a "Book". Para definir enlaces para todos los nodos a una profundidad 1, estableceremos la propiedad Depth a 1. Para definir enlazados para todos los nodos Book que se encuentren a una profundidad 1, estableceremos DataMember a "Book" y Depth a 1, en el objeto TreeNodeBinding.

Una vez que hemos establecido DataMember o Depth para obtener un número concreto de nodos, podemos definir propiedades adicionales de -- para definir la forma de mapear las propiedades del elemento de datos (o atributos del nodo XML, en el caso de datos XML) en propiedades de los TreeNodes que representa el control TreeView. Por ejemplo, la propiedad TextField define el nombre de la propiedad/atributo que usará el "Text" del TreeNode. De forma similar, la propiedad ValuField define la propiedad/atributo del elemento de datos para el "Value" del TreeNode. La propiedad NavigateUrlField define el campo/atributo a usar por el NavigateUrldel TreeNode, y así sucesivamente. Podemos especificar también valores estáticos para las propiedades de TreeNode para un determinado enlazado a datos. Por ejemplo, para especificar que los TreeNodes de los elementos Book tienen una imagen "Book.gif", tendremos que establecer la propiedad ImageUrl del TreeNodeBinding cuyo DataMember está establecido a "Book".

El siguiente ejemplo muestra un TreeView enlazada a los mismos datos XML del ejemplo anterios, con Databindings definidos para elementos específicos de la jerarquía XML.

C# Enlazados a Datos de TreeView



El XmlDataSource soporta una propiedad XPath que podemos usar para filtrar el conjunto de nodos mostrados por la fuente de datos. En el siguiente ejemplo, la propiedad XPath se fija a Bookstore/genre[@name='Business']/book, para filtrar los nodos de la fuente de datos y mostrar sólo aquellos elementos "book" del género "Business". Hay que ir concuidado con especificar la sintaxis correcta para la propiedad XPath, porque si no lo hacemos la fuente de datos no mostrará ningún nodo (y el control de enlazado de datos no los representará)

C# Resultados de un TreeView en un XPath


Observar que la jerarquía de TreeView concuerda del todo con la de la fuente XML. Debido a esto, se suele contruir ficheros XML para venlazarlos al TreeView o para usar una transformación XSL para re-estructurar los datos en una jerarquía más apropiada para el enlazado del TreeView.

C# TreeView de una Transformación XSLT



También es posible enlazar un control tabular enlazado a datos a una fuente de datos jerárquica, aunque el control sólo representará el primer nivel de la jerarquía. En el siguiente ejemplo, un control DataList "templated" se enlaza al mismo fichero XML de los ejemplos anteriores. Debido a que los nodos de nivel superior mostrados por la fuente de datos son nodos <book/>, el DataList podrá enlazar a las propiedades de estos nodos en sus ItemTemplate, mediante expresiones de enlazado de datos Eval.
It is also possible to bind a tabular data-bound control to a hierarchical data source, however the control only renders the first level of hierarchy in this case. In the example below, a templated DataList control is bound to the same bookstore XML file from the preceding example. Because the top-level nodes exposed from the data source are <book/> nodes, the DataList can bind to properties of those nodes in its ItemTemplate using Eval data binding expressions.

C# DataList Enlazado a un Fichero XML



A pesar que representar un nivel de la jerarquía puede ser útil, sería mejor si pudiéramos anidar controles tabulares vinculados a datos  para reflejar la jerarquía subyacente. Afortunadamente, ASP.NET 2.0 nos permite hacer justamente ésto. Además de la sintaxis de enlazado de datos de Eval, ASP.NET 2.0 nos proporciona una sintaxis de vinculado de datos basada en XPath soportada por cualquier elemento de datos que implemente la interfaz IXPathNavigable. Hay dos tipos de expresiones soportadas:
  • XPath(expression, [formatString]) - Evaluates an XPath expression against the data item, returning a single value.
  • XPathSelect(expression, [formatString]) - Evaluates an XPath expression against the data item, returning a selected list of nodes.
El siguiente ejemplo se construye sobre el anterior, utilizando las expresiones de enlazado a datos XPath en lugar de las de Eval para enlazar los atributos de los nodos book. A primera vista parece que no haga nada más que introducir el prefijo '@' a las expresiones, que es la sintaxis XPath para hacer referencia a un atributo nodo. Sin embargo, la flexibilidad real de XPath radica en su habilidad para hacer referencia a elementos arbitrarios dentro de la jerarquía (no sólo atributos).

El ejemplo añade otro DataList al ItemTemplate del DataList más exterior y enlaza la propiedad -- de este DataList interno a una expresión -- que representa la lista de nodos de capítulos del nodo "book" actual. En el ItemTemplate del DataList interno, las expresiones XPath de enlazado de datos se evalúan contreo los nodos de contexto de este "capítulo". Mediante esta técnica, ASP.NET 2.0 nos permite construir fácilmente representaciones de datos jerárquicas y "ricas" mediante controles tabulares.

C# DataList Anidados Enlazados a un Fichero XML


Un control de fuente de datos jerárquica como XmlDataSource asocia una única ruta a cada nodo de su jerarquía, para servir las peticiones de los controles enlazados a datos para nodos de una localización específica. Ésto permite características como la de PopoulateOnDemand del TreeView, dónde los nodos de la fuente de datos se pueden enviar al cliente cuando se expande cada nodo, en lugar de enviarlos todos de una (esta característica se discute de forma más detallada en los ejemplos de la referencia del control TreeView). Eso también nos permite usar esta ruta desde la página de código para configurar la fuente de datos para mostrar los nodos desde una ubicación específica. La sintaxis de la ruta es específica del tipo de datos representados y no se puede construir mediante código. Sin embargo, podermos acceder a la ruta de datos de un nodo enlazado al TreeView mediante la propiedad DataPath del TreeNode. Debido a que XmlDataSource XmlDataSource utiliza expresiones XPath para su sintaxis de la ruta de datos, estas rutas podrían asignarse a la propiedad XPath de un XmlDataSource para filtrar la lista de nodos. El siguiente ejemplo muestra esta técnica para implementar un escenario "master-details" utilizando XmlDataSource. Hay dos controles XmlDataSource, uno vilculado al TreeView (master control) y otro al DataList (details control). Cuando se hace clic sobre un nodo Treeview, se recupera la propiedad DataPath y se asigna al control XmlDataSource enlazado al DataList, para mostrar información adicional del nodo sobre el que se ha hecho clic.

C# Registro de Eventos basado en XML utilizando TreeView(Master-Details)



La sección de Referencia del control TreeView sigue un conjunto de pasos que muestran cómo se escribió este ejemplo partiendo de cero, así que si queréis más información, acudid a dicha sección.

Enlazando a la Navegación del Sitio

La navegación del sitio es otra forma de datos jerárquicos en las aplicaciones ASP.NET. Ésto se describe en la sección Creando una Jerarquía de Navegación del Sitio. Además de soportar la API de Navegación por el Sitio de ASP.NET para acceder de forma programada a los datos del mapa del sitio, ASP.NET 2.0 también soporta un control SiteMapDataSource para enlazar datos de forma declarativa. Cuando enlazamos un control TreeView (o Menu) a un SiteMapDataSource, la propiedades Text y Url del mapa del sitio se pueden enlazar a TreeNodes (o MenuItems). A pesar de que podemos especificar un conjunto de "Databindings" para establecer estos enlaces, esto no es estrictamente necesario. Los controles TreeView y Menu enlazan automáticamente las propiedades Text y NavigateUrl del TreeNode o el MenuItem a las propiedades del mapa del sitio en cuestión (ésto se consigue mediante la interfaz INavigateUIData o SiteMapNode). Otra característica de TreeView y Menu cuando se enlazan a SiteMapDataSource es que se establecen automáticamente las propiedades SelectedNode o SelectedItem al nodo actual dentro del mapa del sitio.

El siguiente ejemplo muestra un TreeView enlazado a un control SiteMapDataSource. A pesar que este ejemplo muestra un grupo de "Databindings" por propositos demostrativos, ésto no es necesario cuando sólo estamos enlazando a las propiedades Text y Url del nodo.

C# TreeView Enlazado a Datos del SiteMap


Enlazando a Bases de Datos Relacionales

Una base de datos relacional también se puede interpretar como una jerarquía cuando las tablas se asocian mediante relaciones de claves externas. Por ejemplo, una base de datos de productos en la que cada producto se asocia con una categoría de productos se puede interpretar como una relación jerárquica (1 a muchos) entre categorías de productos. A pesar que la versión actual de ASP.NET no incluye un control de fuente de datos para mostrar los datos relacionales como jerárquicos, podemos conseguir ésto llenando de forma programada los nodos/elementos de un control enlazado a datos jerárquicos como TreeView o Menu. El siguiente ejemplo muestra un control TreeView llenado desde una base de datos relacional. Este ejemplo aprovecha la característica PopulateOnDemand de TreeView para llenar los nodos hijos "on-demand" (a través de una llamada al servidor) cuando se expande un TreeNode en el cliente. Para más información sobre esta característica, acudir a la sección referencia del control TreeView de este tutorial.

C# Llenando el TreeView desde una Base de Datos