Click here to Skip to main content
Click here to Skip to main content

Master Detail GridView with Insert Option

By , 19 Oct 2009
Rate this:
Please Sign up or sign in to vote.

Introduction

I had to implement a Master-Detail GridView in my application. Searching the net, I did find a lot of solutions, but couldn’t find one where the child table was positioned properly. Well, there might be other solutions that give the same result, but I thought sharing this might help others.

What I have done

I’ve extended the SearchGridView (the last article I posted) and created a NestableGridView class. I overrode the RenderContents function to render the child table in a separate row.

The code

I’ve extended the SearchGridView control as a NestableGridView.

public class NestableGridView : SearchGridView

I’ve overrode the RenderContents function to identify the cell where the child table is and to render it in a separate row.

protected override void RenderContents(HtmlTextWriter writer)
{
    //If there are no rows to be rendered
    if (DesignMode || Rows.Count == 0)
    {
        base.RenderContents(writer);
        return;
    }
    
    //Render the begin tag 
    base.RenderBeginTag(writer);
    //Render header row
    if(HeaderRow != null)
        HeaderRow.RenderControl(writer);
    foreach (GridViewRow row in Rows)
    {
        Control childCtl = row.FindControl(ChildTableID);
        //Render child row by custom method if the child control is visible
        if (childCtl != null && childCtl.Visible)
        {
            row.RenderBeginTag(writer);
            TableCell childCell = null;
            foreach (TableCell cell in row.Cells)
            {
                if (cell.Controls.IndexOf(childCtl) == -1)
                    cell.RenderControl(writer);
                else
                {
                    //If this is the child cell close the table cell
                    writer.Write("<"+"td"+"><"+"/td"+">");
                    childCell = cell;
                }
            }
            //Child control needs to be rendered in the next row
            if(childCell != null)
            {
                writer.Write("<"+"/tr"+"><"+"tr"+">");
                childCell.ColumnSpan = row.Cells.Count;
                childCell.Attributes.Add("align",ChildTableAlign.ToString());
                childCell.RenderControl(writer);
            }
            
            row.RenderEndTag(writer);
        }
        else
        {
            //If the child control is not visible, render thr row
            row.RenderControl(writer);
        }
    }
    //Render Footer Row
    if (FooterRow != null)
        FooterRow.RenderControl(writer);
    //Render Pager Row
    if (PagerRow != null)
        PagerRow.RenderControl(writer);
    base.RenderEndTag(writer);
}

The SelectedIndexChanging event handles the toggling visibility of the child table.

protected override void OnSelectedIndexChanging(GridViewSelectEventArgs e)
{
    base.OnSelectedIndexChanging(e);
    if (DesignMode)
        return;
    if (Rows[e.NewSelectedIndex] != null && 
        Rows[e.NewSelectedIndex].FindControl(ChildTableID) != null)
    {
        Control childCtl = Rows[e.NewSelectedIndex].FindControl(ChildTableID);
        if (childCtl != null)
            childCtl.Visible = !childCtl.Visible;
    }
}

Working sample

Now, let me illustrate the above control with the help of an example. For this purpose, I have used the Categories and Products table from the NorthWind database.

  • Step 1: Create a datasource dsMaster with select query "SELECT * From Categories".
  • Step 2 : Create an instance of NestableGridView and customize the SearchFilters property to have the list of columns on which the search can be performed.
  • Step 3: Create a template column with a SearchGridView with the datasource dsChild and a hidden field _hfChildSearch to hold the search string of the child table. Set the Visibility of the Panel to false to hide all child tables, or true to show all tables initially.
  • Step 4: Set the child table ID of the master grid as pnlChild (the ID of the child table panel).
  • Step 5: Implement the SearchGrid event on the master and child tables to filter and search records.
  • Step 6: Add empty data templates to the master and child tables to insert new records.
  • Step 7: Implement the AddRow event on the master and child tables to add new records to the tables.

Conclusion

NestableGridView can be used not only to display child tables but any control inside the master row, like pictures etc. Also, the alignment of the child row can be set using the ChildTableAlign attribute.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Aparna Lakshminarayanan
Software Developer (Senior)
India India
She has been working on .Net since 2005. Has recently started working on AJAX and ASP .NET and just Loves this technology!

Comments and Discussions

 
GeneralRe: Great work thanks a lot!!! PinmemberAparna Lakshminarayanan21-Oct-09 1:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140415.2 | Last Updated 20 Oct 2009
Article Copyright 2009 by Aparna Lakshminarayanan
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid