Scroll completo para la grilla de ASP.NET

Introducción

Realmente el control del servidor DataGrid que provee el Visual Studio para ASP.NET es muy fácil y cómodo de usar.  Con simplemente establecer un par de propiedades podemos generar un tag <table> con todos sus <tr> y sus <td> a partir de una fuente de datos. Recuerden el trabajo que debíamos tomarnos anteriormente, abrir un recordset, recorrerlo en un bucle y ejecutar Response.Write de cada uno de los tags. Ahora con un simple arrastrar y soltar sobre la página aspx tenemos una tabla con la posibilidad de ordenamiento, paginado, filtrado, edición, etc.

Sin embargo, si decidimos no usar la paginación para evitarnos los round-trips, y la cantidad de registros es considerable, haremos que el usuario necesite desplazar la página para ver la totalidad de los registros.  Esto es contraproducente, ya que el usuario pierde la referencia de la cabecera de la tabla, o podría dejar de ver cierta información relevante como ser un menú ubicado al principio de la página.

Lo ideal es poder darle a la grilla las típicas barras de desplazamiento (scroll) que toda grilla de Windows Forms posee.

Veremos paso a paso la evolución que lleva al resultado final.

Solución

Para agregar barras de scroll, debemos encerrar la grilla en un tag <DIV>, especificar el tamaño de la caja y establecer la propiedad Overflow = auto de CSS (hojas de estilo en cascada), la cual añadirá las barras horizontal y/o vertical según sean necesarias.

<div style="overflow:auto; width:400px; height:201px" >
    <asp:datagrid id=“DataGridFilas” runat="server" DataSource="<%# dataSet11 %>"></asp:datagrid>
<
div/>

El resultado obtenido es el siguiente

A simple vista parece que hemos encontrado la solución, pero no…  Si el usuario desplaza la barra vertical, inmediatamente perderá la referencia a la cabecera de la grilla, como muestra la siguiente figura.

Lo que propongo entonces, es separar la cabecera de las filas usando 2 grillas.  La grilla de la cabecera, DataGridCabecera, estará contenida por un <div> del mismo tamaño de la grilla inferior y tendrá ocultas las barras de desplazamiento.  Dejando habilitadas las barras de desplazamiento para la grilla que contiene las filas solamente, DataGridFilas,

<div style="overflow: hidden; width: 400px">
   
<asp:datagrid id=“DataGridCabecera” runat="server" DataSource="<%# dataSet11 %>"></asp:datagrid>
</
div>
<div style="overflow: auto; width: 400px; height: 201px" >
   
<asp:datagrid id=“DataGridFilas” runat="server" DataSource="<%# dataSet11 %>"></asp:datagrid>
<
div/>

Debemos definir un ancho fijo para las columnas de ambas grillas, ya que generaremos 2 tags <table> distintos.

<div style="overflow: hidden; width: 400px">
    <
asp:datagrid id=“DataGridCabecera” runat="server" DataSource="<%# dataSet11 %>">
       
<Columns>
            <
asp:BoundColumn DataField="ProductID" SortExpression="ProductID" HeaderText
="ProductID">
               
<HeaderStyle Width="80px"></HeaderStyle
>
           
</asp:BoundColumn
>
           
<asp:BoundColumn DataField="ProductName" SortExpression="ProductName" HeaderText
="ProductName">
               
<HeaderStyle Width="250px"></HeaderStyle
>
           
</asp:BoundColumn
>
              
….
        
</Columns
>
    </
asp:datagrid>
</
div>

<div style="overflow: auto; width: 400px; height: 201px" >
     <
asp:datagrid id=“DataGridFilas” runat="server" DataSource="<%# dataSet11 %>">
         
<Columns>
               <
asp:BoundColumn DataField="ProductID" SortExpression="ProductID" HeaderText
="ProductID">
                  
<HeaderStyle Width="80px"></HeaderStyle
>
              
</asp:BoundColumn
>
              
<asp:BoundColumn DataField="ProductName" SortExpression="ProductName" HeaderText
="ProductName">
                  
<HeaderStyle Width="250px"></HeaderStyle
>
               
</asp:BoundColumn
>
              
….
         
</Columns
>
    </
asp:datagrid>
<
div/>

La grilla original DataGridFilas, debe ocultar la cabecera para no mostrarse 2 veces; para ello crearemos una clase de CSS llamada Esconder, que reduce el tamaño al 1%.

<STYLE>
   
.Esconder {zoom=1%;}
</STYLE>

Y se la aplicaremos al HeaderStyle de la grilla:

<div style="overflow: hidden; width: 400px">
    <
asp:datagrid id=“DataGridCabecera” runat="server" DataSource="<%# dataSet11 %>">
       
<Columns>
            <
asp:BoundColumn DataField="ProductID" SortExpression="ProductID" HeaderText="ProductID">
               
<HeaderStyle Width="80px"></HeaderStyle>
           
</asp:BoundColumn>
           
<asp:BoundColumn DataField="ProductName" SortExpression="ProductName" HeaderText="ProductName">
               
<HeaderStyle Width="250px"></HeaderStyle>
           
</asp:BoundColumn>
              
….
        
</Columns>
    </
asp:datagrid>
</
div>

<div style="overflow: auto; width: 400px; height: 201px" >
     <
asp:datagrid id=“DataGridFilas” runat="server" DataSource="<%# dataSet11 %>">
         <HeaderStyle CssClass="Esconder"></HeaderStyle>
         
<Columns>
               <
asp:BoundColumn DataField="ProductID" SortExpression="ProductID" HeaderText="ProductID">
                  
<HeaderStyle Width="80px"></HeaderStyle>
              
</asp:BoundColumn>
              
<asp:BoundColumn DataField="ProductName" SortExpression="ProductName" HeaderText="ProductName">
                  
<HeaderStyle Width="250px"></HeaderStyle>
               
</asp:BoundColumn>
              
….
         
</Columns>
    </
asp:datagrid>
<
div/>

La nueva grilla DataGridCabecera que muestra la cabecera no se vinculará a la fuente de datos, de forma tal de no crear las filas que muestran los registros. Este es el código asociado a la carga de la página.  Las 2 grillas están asociadas al dataSet11, sin embargo solo DataGridFilas mostraré las filas ya que el DataSet no esta caragado aún cuando DataGridCabecera.DataBind() es ejecutado.

private void Page_Load(object sender, System.EventArgs e)
{
    DataGridCabecera.DataBind();
    sqlDataAdapter1.Fill(dataSet11);
    DataGridFilas.DataBind();
}

Este es el resultado obtenido:

¿Qué pasa, si el usuario mueve la barra de deslizamiento horizontal?  Se moverán las filas lateralmente y quedará fija la cabecera. ¡Que feo!.

Completemos la solución: lo que necesitamos es poder desplazar la cabecera, DataGridCabecera, tantos píxeles como la barra de desplazamiento que contiene a la grilla DataGridFilas se deslice.

En el evento onscroll del <div> que muestra las barras de desplazamiento, agregaremos código Javascript para sincronizar el movimiento lateral de las filas con la cabecera, de forma tal de mover la cabecera tantos píxeles como lo haga la barra de desplazamiento horizontal. Es necesario entonces que la grilla cabecera DataGridCabecera tenga una posición relativa al <div> que la contiene para poder moverla: style="position: relative".

<STYLE>
   
.Esconder {zoom=1%;}
</STYLE>

<script language="JScript">
   
function DoScroll()
    {
        document.all(
"DataGridCabecera").style.pixelLeft = divScroll.scrollLeft * -1;
    }
</script>

<div style="overflow: hidden; width: 400px">
    <
asp:datagrid id=“DataGridCabecera” runat="server" style="position:relative" DataSource="<%# dataSet11 %>">
       
<Columns>
            <
asp:BoundColumn DataField="ProductID" SortExpression="ProductID" HeaderText="ProductID">
               
<HeaderStyle Width="80px"></HeaderStyle>
           
</asp:BoundColumn>
           
<asp:BoundColumn DataField="ProductName" SortExpression="ProductName" HeaderText="ProductName">
               
<HeaderStyle Width="250px"></HeaderStyle>
           
</asp:BoundColumn>
              
….
        
</Columns>
    </
asp:datagrid>
</
div>
<div style="overflow: auto; width: 400px; height: 201px" id="divScroll" onscroll="DoScroll()">
     <
asp:datagrid id=“DataGridFilas” runat="server" DataSource="<%# dataSet11 %>">
         <HeaderStyle CssClass="Esconder"></HeaderStyle>
         
<Columns>
               <
asp:BoundColumn DataField="ProductID" SortExpression="ProductID" HeaderText="ProductID">
                  
<HeaderStyle Width="80px"></HeaderStyle>
              
</asp:BoundColumn>
              
<asp:BoundColumn DataField="ProductName" SortExpression="ProductName" HeaderText="ProductName">
                  
<HeaderStyle Width="250px"></HeaderStyle>
               
</asp:BoundColumn>
              
….
         
</Columns>
    </
asp:datagrid>
<
div/>

De esta forma tendremos una grilla con la funcionalidad de desplazamiento idéntica a un control Windows Forms.

Descargar codigo completo

Conclusión

El uso de herramientas como CSS (Hojas de estilo en cascada) y DHTML son perfectamente factibles de combinar con los nuevos elementos que introduce ASP.NET permitiéndonos crear interfaces de usuario mas amigables.

Este artículo fue publicado originalmente en la revista MTJ.NET de MSDN Latinoamérica en Diciembre del 2003

Agregar a Technorati
Published Wednesday, November 14, 2007 8:38 AM by cwalzer
Filed under: , ,

Comments

# re: Scroll completo para la grilla de ASP.NET

Wednesday, December 12, 2007 12:35 PM by Ivan Alcaman

y el ordenamiento por columnas la paginacion...se pieerde todo eso ...una cosa por otra...la idea de usar dos grillas no me gusta...ademas esta solucion al ingresarle palabras de 200 caracteres sin espacios las celdas se descuadran

SAludos

# ComoLoHagoFacil: Cómo agregar scrolls a una grilla en ASP.NET

Tuesday, August 26, 2008 9:18 AM by Blog de la comunidad MSDN en Español

Matias Iacono nos muestra en menos de 5 minutos cómo agregar Scroll a un GridView en ASP.NET . Para los

# re: Scroll completo para la grilla de ASP.NET

Thursday, October 16, 2008 3:27 PM by Gabriel

muchas gracias, es lo que andaba buscando

# re: Scroll completo para la grilla de ASP.NET

Wednesday, October 29, 2008 5:20 PM by Jorge

Me parece estupenda la aportación , gracias

Leave a Comment

(required) 
(required) 
(optional)
(required) 
Powered by Community Server (Commercial Edition), by Telligent Systems