DataGrid With a Title Row

0 comments suggest edit

One thing I’ve found annoying at times with the DataGrid control is there’s no way to specify a title to be displayed above the headers. Being lazy, I often resorted to adding a label above the data grid followed by a br tag.

But no longer! I wanted to have the title display in its own row within the data grid structure so I created a custom data grid control that does just that. See the example below for how it renders.

This is the Title
Column 1 Column 2 Column 3
See Spot Run
Run Spot Run!
Flee the Maniacs

The key to this is to override the OnItemCreated method and set my own rendering method for the header item.

/// <summary>
/// Assigns our own render method for the header item.
/// </summary>
/// <param name="e"> E. </param>
protected override void OnItemCreated(DataGridItemEventArgs e)
{
    if (ListItemType.Header == e.Item.ItemType && Title != null &&
Title.Length > 0)
    {
        e.Item.SetRenderMethodDelegate( new RenderMethod(RenderTitle));
    }
    else
    {
        base .OnItemCreated(e);
    }
}

When ASP.NET is ready to render the Header, it’ll call my method instead which is named RenderTitle.

/// <summary>
/// Renders the title as its own row.
/// </summary>
/// <param name="writer"> Writer. </param>
/// <param name="ctl"> CTL. </param>
protected virtual void RenderTitle(HtmlTextWriter writer, Control ctl)
{
    // TR is on the stack writer's stack at this point...
    writer.AddAttribute(
        "colspan",
        this.Columns.Count.ToString(CultureInfo.InvariantCulture));

    writer.AddAttribute("align", "center");
    writer.RenderBeginTag("TD");
    writer.Write(Title);
    writer.RenderEndTag(); // Writes </TD>
    writer.RenderEndTag(); // Writes </TR>

    // Now we add the header attributes we
    // copied.
    this .HeaderStyle.AddAttributesToRender(writer);
    writer.RenderBeginTag("TR");

    //Render the cells for the header row.
    foreach (Control control in ctl.Controls)
    {
        control.RenderControl(writer);
    }

    // We don't need to write the </TR>.
    // The grid will do that for us.
}

The snippet shown here will style the title row the same as the header style. In my actual control, I defined a property named TitleCssClass to enable you to define your own Css class to use to style the title row. This required me to do a bit of hacking so that the HeaderStyle gets removed from the render stack and then gets added back later when rendering the Header row. If that makes no sense, you’ll see what I mean. I’ve put the code for the control here.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

4 responses

  1. Avatar for James Gregory
    James Gregory June 20th, 2006

    Interesting article, first time i've seen use of the 'SetRenderMethodDelegate' method, must investigate.
    Did you try using the Caption attribute of the DataGrid for this purpose? It doesn't create a cell as such, but it does create a fully stylable tag for the table, more semantically correct for those buffs too.

  2. Avatar for Haacked
    Haacked June 21st, 2006

    Ah, when I wrote that article, I didn't know about the caption. I should look into that.

  3. Avatar for James Gregory
    James Gregory June 21st, 2006

    It occurred to me that maybe that was the case, baring in mind your post is now over a year old! My bad.
    This Microsoft KB article covers the the Caption and UseAccessibleHeader attributes, both which are useful additions to the DataGrid, definitely welcome.

  4. Avatar for Aleš
    Aleš July 10th, 2006

    Great example. By changing item type checking to ListItemType.EditItem I was able to write custom edit row.
    Thanks