Much better scrolling with Datagrid

I am not happy with the usual scrolling tip you can find everywhere about Datagrids.

Why ? Because you have an external scrolling, so when you scroll, you lost the headings :-(

As you can see in this example, if I have a long list I lost the header.

Most of the solutions are based on the duplication of the Header to a Table on top of the Datagrid.
It's not really good, because you lost the flexibility of the Datagrid attributes and styles.


After a long search, I finally found an answer.. from MSDN ;-)

I adapt this to the Datagrid, and it's working perfectly as you can see in this screenshot of my CMS !

The things to know is you need an .htc file, so obviously this solution is for IE only.
But if you are building an Intranet or an admin page, this is really neat.

The main table created with Datagrid has a stylesheet embedding with the call to this htc code.

Scroll.htc

<PUBLIC:ATTACH event="ondocumentready" handler="onDocumentReady" />
<SCRIPT language="JScript">
function onDocumentReady()
{
   // Create elements
   var tblHeader = this.cloneNode(false);
   var tblBody   = this.cloneNode(false);
   var divCntr   = document.createElement("DIV");

   // Get column widths
   var rgWidths = new Array();
   for (var i = 0; i < this.rows[0].cells.length; i++)
   {
      rgWidths[i] = this.rows[0].cells[i].offsetWidth;
   }

   // Add header row
   var tbdyHeader = document.createElement("TBODY");
   tblHeader.appendChild(tbdyHeader);
   tbdyHeader.appendChild(this.rows[0].cloneNode(true));

   // Add body rows
   var tbdyBody = document.createElement("TBODY");
   tblBody.appendChild(tbdyBody);
  
   for (var i = 1; i < this.rows.length; i++)
   {
      var oRow = this.rows[i].cloneNode(true);
      tbdyBody.appendChild(oRow);
   }

   // Set up body container
   divCntr.style.overflow = "auto";
   if (this.bodyHeight) divCntr.style.height = this.bodyHeight;
   divCntr.appendChild(tblBody);

   // Change existing table
   for (var i = this.rows.length; i > 0; i--)
   {
      this.rows[i-1].removeNode(true);
   }
   var tr1 = this.insertRow();
   var td1 = tr1.insertCell();
   var tr2 = this.insertRow();
   var td2 = tr2.insertCell();
  
   td1.appendChild(tblHeader);
   td2.appendChild(divCntr);

   // Set column widths of all but the last column
   for (var i = 0; i < rgWidths.length - 1; i++)
   {
      tblHeader.rows[0].cells[i].width = rgWidths[i];  
      tblBody.rows[0].cells[i].width   = rgWidths[i];
   }

   tblHeader.style.fontSize    = "100%";
   tblHeader.width             = "100%";
   tblHeader.style.tableLayout = "fixed";
   tblHeader.className         = this.headerCSS ? this.headerCSS : "";
   tblHeader.border = 0;

   tblBody.style.fontSize      = "100%";
   tblBody.width               = "100%";
   tblBody.style.tableLayout   = "fixed";
   tblBody.className           = this.bodyCSS ? this.bodyCSS : "";
   tblBody.border = 0;

   this.cellSpacing = 0;
   this.cellPadding = 0;
}
</SCRIPT>

In the ASP.Net page, where you implement your Datagrid, you need to have the styles below in the <Head> section (eventually you can link to an external stylesheet):

<STYLE>
.tblMain
{
   behavior:url(scroll.htc);
   background-color: highlight;
   border: 1px solid darkblue;
   font-family: Verdana;
   font-size: .8em;
}
.tblHeader
{
   color: highlighttext;
}
.tblBody
{
   background-color: #EEEEEE;
   color: darkblue;
}
</STYLE>

And finally the Datagrid object (in red and bold the specific parts). This example is the code for the Datagrid shown in the screenshot above :

<asp:datagrid bodyHeight="100" bodyCSS="tblBody" headerCSS="tblHeader"
   cssclass="tblMain" id="DGVersions" Runat="server"  AutoGenerateColumns="false" Font-Size="8"
         HeaderStyle-Font-Bold="True" HeaderStyle-HorizontalAlign="Center" Width="280">
         <AlternatingItemStyle CssClass="Alt" />
         <Columns>
          <asp:BoundColumn DataField="SectionVersion" HeaderText="Version" HeaderStyle-Width=100 ItemStyle-Width="100"  ItemStyle-HorizontalAlign=center/>
          <asp:BoundColumn DataField="DateCreation" headertext="Created"  HeaderStyle-HorizontalAlign=Center HeaderStyle-Width=100 ItemStyle-Width="100"  />
          <asp:TemplateColumn ItemStyle-Width=50>
           <ItemTemplate>
            <asp:ImageButton ID="ButDelVersion" Runat="server" ImageUrl="~/images/delete.gif" CommandName="Delete" />
            <asp:ImageButton ID="ButEditVersion" Runat="server" imageurl="~/images/edit.gif" CommandName="Edit" />
           </ItemTemplate>
          </asp:TemplateColumn>
         </Columns>
        </asp:datagrid>


This is indeed a first version, and I have to fix some stuff like:

- Alternative colors for the datagrid rows
- Writing a Javascript equivalent code to make the scroll working with other browsers.

I hope also that this scroll idea will be part of ASP.Net 2.0 natively ;-)

 

9 Comments

  • Hi there ...



    That is really the great stuff.Actually can you please tell me is it possible to freeze the column in the datagrid the way we can do the freezing in the Excel sheet.



    Please give me the guidelines for this. Thanks in advance.



    Regards

    Raman Kohli

    Raman.Kohli@lntinfotech.com

  • heh Raman, any luck with freezing columns in the datagrid

  • Infragistics does that in their components(not for free).

  • please tell me how i can make horizontal scrolling with the same script

  • Yes, please tell us how to have fixed horizontal scrolling.

  • Hi, I tried and I manage to have the Header of the datagrid freeze.



    But when the Datagrid is in the edit mode, it does not capture the Default value for the Drop Drop list box.



    Is there a solution?



    Regards,

    pllms





  • It works in my station where i devlope, but in client browser i get error. the client's browser version in 6.0 :(

  • This is great! Thanks for the tip, I'm using it on an intranet site I'm building.



    It is very easy to add alternating colors for rows. Just add in AlternatingItemStyle-BackColor=&quot;#eeeeee&quot; in the asp:DataGrid element.



    Now to figure out how to allow items to be moved up and down in the list...

  • Hi,

    I would have a datagrid that scrolls only the contents but not the pager; is possible to freeze also the pager? Thanks,



    Regards,

Comments have been disabled for this content.