Por ejemplo, vamos a analizar “List.aspx”, la página que permite listar los registros de cualquier tabla de datos.
Lo primero que examinaremos será su código, contenido en List.aspx.vb o List. aspx.cs según uses vB o c# como lenguaje de desarrollo.
el código define un variable protegida de ámbito de página llamada table y de tipo MetaTable. esta clase System.Web.DynamicData.Metatable encapsula los metadatos de una tabla/entidad que está siendo manejada por Dynamic Data. a través de sus miembros tenemos acceso a la información sobre el modelo de datos subyacente. así, por ejemplo, podemos averiguar el nombre de la tabla con su pro- piedad DisplayName, o conocer los detalles de sus campos a través de su colección Columns. La referencia completa la tienes aquí:
http://msdn.microsoft.com/es-es/library/system.web.dynamicdata.metata- ble_members.aspx
en el evento Load de la página/plantilla se asigna a este miembro, table, los metadatos de la tabla actualmente manejada en la plantilla, de forma que se pueda
hacer uso de ella desde cualquier parte de la página para mostrar información sobre la entidad gestionada. en la versión 3.5 sP1 el código de asignación es este:
table = GridDataSource.GetTable
GridDataSource es como se llama el control LinqDataSource o EntityDataSource
(según la tecnología de datos que hayamos elegido) que se encarga de hacer el acceso a los datos en la plantilla. estos controles han sido extendidos con algunas propiedades y métodos como este (GetTable) para dar soporte a Dynamic Data.
en asP.NeT 4.0 el código equivalente utilizado es el siguiente:
table = GridQueryExtender.SetTableFromRoute
en ese caso se usa el método SetTableFromRoute de un control QueryExtender incluido en la página para hacer filtrado de datos (ver capítulo correspondiente en este libro). Lo que hace es obtener una referencia al modelo de tabla apropiado basándose en la ruta actual de la página (ver epígrafe 8 de este capítulo), pero es exactamente lo mismo que el código anterior. De hecho podríamos haber usado el mismo aquí también en lugar de este.
Los metadatos de la tabla nos ofrecen el método GetActionPath, que nos informa de la ruta apropiada para realizar las distintas acciones sobre la entidad. así, por ejemplo, para obtener la ruta que genera la página de inserción para la entidad actual podríamos usar:
table.GetActionPath(PageAction.Insert)
Lo mismo con el resto de acciones: edición (PageAction.Edit), detalles (Pageac- tion.Details) y listado de registros (PageAction.List). en asP.NeT 4.0 esto no es necesario porque el nuevo control DynamicHyperLink se encarga de esto automáti- camente como veremos ahora mismo
analicemos ahora el marcado hTML de página.
si analizas los controles incluidos verás que, quitando un par de ellos, todos los demás son controles normales de asP.NeT, como una rejilla y un control Da-
taSource.
el primer control que nos encontramos es un DynamicDataManager. La funcio- nalidad de Dynamic Data se basa en el uso de unos cuantos controles especiales que habilitan el enlazado automático con el modelo de datos. como ya he comentado en la introducción, algunos controles como las rejillas se han modificado para soportar enlazado dinámico a datos y de esta manera generar listados y editar registros ba- sándose en las plantillas. el control DynamicDataManager es un control no visual cuya función precisamente es habilitar este soporte dinámico en ciertos controles de la página. en concreto las tareas que realiza son:
Generar en los controles
• GridView o DetailsView las columnas necesarias para
ajustar el tipo de contexto de datos y el nombre de la tabla en el control •
LinqDataSource o EntityDataSource para que puedan trabajar con la tabla
de datos correcta.
establecer los parámetros de filtrado (
• WhereParameters) en el control origen
de datos para poder hacer filtros.
cargar automáticamente las claves externas en el caso de modelos Linq. •
si miras un poco más abajo en el código verás una rejilla, GridView1, que será la encargada de listar los registros de datos, función principal de esta página. en este caso, como este es el control que utilizaremos con Dynamic Data, deberá ser activado para que soporte los controles dinámicos, por eso la plantilla tiene este marcado:
<asp:DynamicDataManager ID=”DynamicDataManager1” runat=”server” AutoLoadForeignKeys=”true”>
<DataControls>
<asp:DataControlReference ControlID=”GridView1” /> </DataControls>
</asp:DynamicDataManager>
Lo que estamos indicando de manera declarativa es que el control DynamicData-
Manager debe habilitar el soporte para controles dinámicos en la rejilla GridView1.
esto es lo que activa realmente toda la funcionalidad de la rejilla, pues a partir de este momento el control de origen de datos asociado a ésta (un LinqDataSource en nuestro ejemplo) ya sabrá qué datos debe manejar, y los controles dinámicos contenidos en la rejilla podrán mostrar la información.
De hecho la rejilla está configurada para generar automáticamente las columnas a partir de todos los campos que haya en la entidad de datos que maneje. Los dos elementos definidos en su <itemTemplate> son simples enlaces para editar y ver los detalles del registro actual. el resto de los campos se genera al vuelo.
Una cuestión importante a tener en cuenta si utilizas asP.NeT 3.5 sP1 es que, en esta primera versión de Dynamic Data, no estaba soportada la activación decla- rativa de los controles como acabamos de ver, y debía activarse mediante código al inicializar la página, así:
Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs)
DynamicDataManager1.RegisterControl(GridView1, True) End Sub
Lo que sería equivalente al marcado anterior. Tenlo en cuenta si intentas repro- ducir estos ejemplos en una versión anterior a visual studio 2010.
La paginación de la rejilla se efectúa con un control llamado <asp:GridViewPager>. No lo busques en el modelo de objetos de asP.NeT pues no es un control estándar a pesar de que lleva el prefijo asp (deberían haber elegido otro más claro). en realidad
es un control de usuario que encontrarás en la subcarpeta “DynamicData\content”. Por defecto incluye botones para avanzar por las páginas, un cuadro de texto para saltar a una página directamente, y una lista desplegable para elegir el número de elementos por página.
Figura 6.- barra de paginación de los listados automáticos
si editamos este control (GridViewPager.ascx) podremos personalizar com- pletamente el aspecto y funcionalidad de la paginación de registros. Los gráficos utilizados están en esa misma carpeta dentro de “Images”.
especial mención merece la forma en la que se generan los filtros automáticos para el listado.
el control utilizado es un QueryableFilterRepeater. este control no lo encontra- rás en la barra de herramientas de visual studio y es necesario añadirlo a mano a la página. su función es la de generar los controles que pueden usarse para filtrar los registros de la rejilla. Por defecto se generan controles en forma de lista desplegable para todos los campos que son una clave externa de la tabla y para los campos booleanos. este control repetidor se usa para filtrar datos en el DataSource corres- pondiente usando para ello un control QueryExtender (ver capítulo 7).
en la figura 7 podemos ver los filtros automáticos que se han generado para la tabla de productos que son tres: uno para el único campo booleano (si el producto está o no descatalogado) y otros dos para las tablas relacionadas con la actual (ca- tegorías y proveedores).
Figura 7.- Filtros automáticos para tablas. Nota:
en la primera versión de Dynamic Data, en asP.NeT 3.5 sP1, no existen estos controles, por lo que se utiliza en su lugar un control FilterRepeater. este control proporciona directamente al origen de datos una lista de parámetros Where que realizan el filtro, ya que no existe tampoco el control QueryExtender, disponible sólo a partir de asP.NeT 4.0.
el control desplegable se puede cambiar por cualquier otro o también es posible modificar su comportamiento partiendo del original. Para ello podemos modificar la plantilla apropiada dentro de la subcarpeta “Filters” que se ve en la figura 5 y que, por defecto, contiene una plantilla para los booleanos, otra para las enumeraciones y una tercera para las tablas relacionadas, que es la que se ha utilizado aquí.
el resto de las páginas/plantillas son tremendamente parecidas, por lo que no te costará mucho comprender su funcionamiento y poder manipularlas a tu antojo.
asegúrate de entenderlas bien porque, al hacerlo, tendrás casi todo lo que nece- sitas para crear tus propias páginas que saquen partido a Dynamic Data, pero sin tener que usar la generación automática de código. Luego volveremos sobre ello.
6.- PlANTillAS PArA ENTidAdES
Una de las cosas que probablemente te llamará la atención cuando analices las planti- llas anteriores es que, en las páginas de detalles, la edición o la inserción de registros, se emplea un control llamado DynamicEntity. se trata de una nueva característica introducida en la versión 4.0 de la plataforma que permite tener mayor control sobre la forma de generar las interfaces de trabajo con elementos individuales.
en la primera versión de Dynamic Data los registros individuales se mostraban tal cual estaban definidos en las plantillas “Details.aspx”, “edit.aspx” e “Insert. aspx”. Desde la versión 4.0 es posible hilar más fino y definir plantillas de edición especiales para cada tipo de entidad.
Para ello en la carpeta “entityTemplates” hay tres plantillas para trabajar con entidades individuales: visualización (“Default.ascx”), edición (“Default_edit.ascx”) e inserción (“Default_Insert.ascx”) respectivamente. Éstas contienen el código de marcado que se usará para realizar cada una de estas acciones con todos los tipos de entidades.
Podemos crear nuestras propias plantillas especiales para entidades concretas con tan solo crear controles análogos a estos con el nombre de la entidad/tabla. Por ejemplo, para ajustar a nuestra voluntad el trabajo con los registros de la tabla de productos podemos crear los controles: “Products.ascx”, “Products_edit.ascx” y “Products_Insert.ascx”. No es obligatorio crear los tres, sólo los que nos interesen.
en tiempo de ejecución los controles DynamicEntity de las páginas plantilla se sustituyen por el control apropiado de la carpeta “entityTemplates”.