help.net


Musing on .Net

News

Windows Phone Apps I recommend

FotoBank


FotoIreland



hit counters






Open source CMS


My blog

Irish blogs

Locations of visitors to this page Get Chitika eMiniMalls

.Net useful

Blogs I read

PocketPC

SQL

Usability

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 ;-)

 

Posted: Sep 10 2003, 11:26 AM by help.net | with 14 comment(s)
Filed under:

Comments

No Comments