views:

202

answers:

1

Goal: For each row in the grid render a row under it that colspans all of the columns in the grid.

Why: So that we can nest grids in that row or maybe a form for a quick edit or maybe an update panel.

Challenge: In RowDataBound, RowCreated the row that you are working with has not yet been added to the root table. This makes it easy if you want to add a row before that row you can cast the e.row.parent control as table and add the row to it. When you do that it will show up before the current row you are working with.

Example:

protected void Page_Load(object sender, EventArgs e)
{

    List<String> strings = new List<string>();
    strings.Add("Test1");
    strings.Add("Test2");
    strings.Add("Test3");

    CustomGridView GridView1 = new CustomGridView();
    GridView1.DataSource = strings.Select(s => new { Column1 = s });
    GridView1.DataBind();

    phGrid.Controls.Add(GridView1);
}

public class CustomGridView : GridView
{
    public Table Table
    {
        get;
        set;
    }

    public CustomGridView()
    {
        this.RowCreated += new GridViewRowEventHandler(CustomGridView_RowCreated);
    }

    protected override Table CreateChildTable()
    {
        Table = base.CreateChildTable();
        return Table;
    }

    GridViewRow lastRow;
    void CustomGridView_RowCreated(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow || e.Row.RowType == DataControlRowType.Footer)
        {
            if (lastRow != null)
                this.Table.Rows.Add(CreateRow());

            lastRow = e.Row;
        }
    }

    private static GridViewRow CreateRow()
    {
        GridViewRow newRow = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);

        TableCell cell = new TableCell();
        cell.Controls.Add(new LiteralControl("&nbsp;&nbsp;FormRow"));

        newRow.Cells.Add(cell);

        return newRow;
    }
}

alt text

Issues: The codesmell is a little bit more than I would like with this code. I don't like that I need to keep track of the last data row because it is hard for junior developers to comprehend the iterative nature of this code for maintenance.

Question: Does anyone know what gets called just after row created? When is the row actually added to the root table and can I override a method to participate with it. I have decompiled the GridView class with Reflector and I just can't see to find what I am looking for.

A: 

Quick and dirty as can, but you could consider adding something like:

<asp:Literal ID="ltlExtraRow" runat="server">
</tr>
  <tr>
     <td colspan="9">x</td>
     <td colspan="8">y</td>
</asp:Literal>

in the last column (itemtemplate) of your gridview

Arnoldiuss