Click here to Skip to main content
11,705,208 members (41,850 online)
Click here to Skip to main content

Editable Nested GridView (All-in-One)

, 16 Aug 2007 CPOL 404.5K 15.9K 246
Rate this:
Please Sign up or sign in to vote.
How to create an all-in-one editable nested GridView in ASP.NET using C#.

Screenshot - EditNestedGridView.jpg

Introduction

This article explains how to make an ASP.NET editable nested GridView. Here I am going to explain how to provide all the features of Edit/Add/Delete/Update/Page/Sort of a GridView, and not only one GridView, but I am going to explain how to extend these features to even nested grids (GridView inside GridView). I have provided the fully functional source code, which is self-explanatory.

Background

My previous article explains about the features of nested editable DataGrids. This article provides all those features in a GridView (Visual Studio 2005, .NET 2.0). With the combination of GridView and DataSource controls, it's very easy to create an editable GridView.

Using the Code

This is a web application with a virtual directory named EditNestedGridView. You may create the same virtual directory to run this application with Visual Studio .NET 2005, or create any other virtual directory and map the path to this directory to access it from the browser. As I have used Access 2003 as my database, you need to have Microsoft Access installed on your machine. I have used the NorthWind database with some modifications. I have also included this in the code bundle under the App_Data folder. I have used C# for the code-behind files. In Visual Studio 2005, File --> Open --> Web Site, and navigate to the folder EditNestedGridView.

Step-by-Step Procedure

The code attached is self-explanatory, but I will try to explain it as much as possible.

  1. Since here I am going to use the DataSource control, let's first create an AccessDataSource control as below:
  2. <asp:AccessDataSource ID="AccessDataSource1" runat="server" 
        DataFile="App_Data/Northwind.mdb" 
        SelectCommand="SELECT [Customers].[CustomerID], 
        [Customers].[CompanyName],[Customers].[ContactName],
        [Customers].[ContactTitle],[Customers].[Address] FROM [Customers] 
        ORDER BY [Customers].[CustomerID]"></asp:AccessDataSource>

    The main advantage of the DataSource control is that it simplifies the amount of custom code that needs to be written to retrieve and bind data, and even to sort, page through, or edit data.

  3. Now, let's create a simple GridView control and attach the previously created DataSource control as shown below:
  4. <asp:GridView ID="GridView1" AllowPaging="True" BackColor="#f1f1f1" 
                AutoGenerateColumns=false DataSourceID="AccessDataSource1" 
                DataKeyNames="CustomerID"
                style="Z-INDEX: 101; LEFT: 8px; POSITION: absolute; TOP: 32px" 
                ShowFooter=true Font-Size=Small
                Font-Names="Verdana" runat="server" GridLines=None BorderStyle=Outset>

    GridView is very similar to DataGrid and it has all those column features of DataGrid like TemplateColumn, BoundColumn to populate data as columns. EditItemTemplate and FooterTemplate can be used for editing and adding purposes. The following code shows the columns of the parent grid:

    <asp:TemplateField HeaderText="Customer ID" SortExpression="CustomerID">
        <ItemTemplate>
            <asp:Label ID="lblCustomerID" Text='<%# Eval("CustomerID") %>' 
                runat="server"></asp:Label>
        </ItemTemplate>
        <EditItemTemplate>
            <asp:Label ID="lblCustomerID" Text='<%# Eval("CustomerID") %>' 
                runat="server"></asp:Label>
        </EditItemTemplate>
        <FooterTemplate>
            <asp:TextBox ID="txtCustomerID" Text='' runat="server"></asp:TextBox>
        </FooterTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Company Name" SortExpression="CompanyName">
        <ItemTemplate><%# Eval("CompanyName") %></ItemTemplate>
        <EditItemTemplate>
            <asp:TextBox ID="txtCompanyName" Text='<%# Eval("CompanyName") %>' 
                runat="server"></asp:TextBox>
        </EditItemTemplate>
        <FooterTemplate>
            <asp:TextBox ID="txtCompanyName" Text='' runat="server"></asp:TextBox>
        </FooterTemplate>
    </asp:TemplateField>
    ..........................
    ..........................
    
    <asp:CommandField HeaderText="Edit" ShowEditButton="True" />
    <asp:TemplateField HeaderText="Delete">
        <ItemTemplate>
            <asp:LinkButton ID="linkDeleteCust" CommandName="Delete" 
                runat="server">Delete</asp:LinkButton>
        </ItemTemplate>
        <FooterTemplate>
            <asp:LinkButton ID="linkAddCust" CommandName="AddCustomer" 
                runat="server">Add</asp:LinkButton>
        </FooterTemplate>
    </asp:TemplateField>

    Now that we have all the columns in place, we need the event handlers to take care of the Add/Edit/Delete actions. Handling these events is very straightforward compared to that for the DataGrid. The DataSource control takes care of the paging and sorting actions. Here is the final parent GridView control with all these events.

    <asp:GridView ID="GridView1" AllowPaging="True" BackColor="#f1f1f1" 
                AutoGenerateColumns=false DataSourceID="AccessDataSource1" 
                DataKeyNames="CustomerID"
                style="Z-INDEX: 101; LEFT: 8px; POSITION: absolute; TOP: 32px" 
                ShowFooter=true Font-Size=Small
                Font-Names="Verdana" runat="server" GridLines=None 
                OnRowDataBound="GridView1_RowDataBound" 
                OnRowCommand = "GridView1_RowCommand" 
                OnRowUpdating = "GridView1_RowUpdating" BorderStyle=Outset
                OnRowDeleting = "GridView1_RowDeleting" 
                OnRowDeleted = "GridView1_RowDeleted"
                OnRowUpdated = "GridView1_RowUpdated" AllowSorting=true>

    With all the above options, the GridView looks like:

    Screenshot - EditNestedGridView1.jpg

  5. Until now, we have created a parent GridView. Now we are going to extend these features in a child GridView as well.
  6. Before adding another GridView, we must understand how GridView emits its content as HTML tags. For an Internet Explorer browser, GridView is like a regular Table with TR and TD tags. So, if we can manipulate the parent GridView to forcibly close a row and emit a child GridView as another row, we are done with it.

    What is displayed is some HTML table cell and row tags that effectively intercept the current output that will be generated by the GridView with our own special implementation. Namely, we are telling the table (when it's drawn) to close the current cell, the current row, and now add a new row with one blank column (for spacing) and another column (spanning all columns) that we'll use to display a second GridView. Here is the piece of code which explains this:

    <asp:TemplateField>
        <ItemTemplate>
            <tr>
            <td colspan="100%">
            <div id="div<%# Eval("CustomerID") %>" 
                style="display:none;position:relative;left:15px;OVERFLOW: auto;WIDTH:97%" >

    Here, I have created a division id="div Eval("CustomerID") with an ID of Customer (parent row) which holds the child GridView so that we can dynamically hide and expand it by using the DIV ID. Also, we need a column in the main GridView which holds the image to expand and collapse the child GridView as below:

    <asp:TemplateField>
        <ItemTemplate>
            <a href="javascript:expandcollapse('div<%# Eval("CustomerID") %>', 'one');">

    Here, the JavaScript function expandcollapse will take care of the expand and collapse action.

  7. In order to bind the child GridView, we can't use the static DataSource control as we have used for the parent GridView. We will have to dynamically prepare the query based on the customer ID of the corresponding parent row, and that we can do it in the RowDataBound event of the parent grid as below:

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        GridViewRow row = e.Row;
        string strSort = string.Empty;
    
        // Make sure we aren't in header/footer rows
        if (row.DataItem == null)
        {
            return;
        }
    
        //Find Child GridView control
        GridView gv = new GridView();
        gv = (GridView)row.FindControl("GridView2");
    
        //Prepare the query for Child GridView by passing 
        //the Customer ID of the parent row
        gv.DataSource = 
            ChildDataSource(((DataRowView)e.Row.DataItem)["CustomerID"].ToString(), 
            strSort);
        gv.DataBind();
    }

    Here, the ChildDataSource function forms the query using the passed customer ID and returns the AccessDataSource.

  8. Now, we have data in the child grid as well, with dynamic expand and collapse. Let's add the effects one by one as we did for the parent grid. However, before going further, there is a little tricky part involved. In the case of the parent grid, there is only a unique ID (GridView1), and in the case of the child, there will be several unique IDs that get generated at run time. If we can identify the one which we need, that will solve this problem.

    Paging and sorting were taken care of by the DataSource control in the case of the parent grid. For the child grid, we have to take care of it manually using the corresponding events PageIndexChanging and Sorting. A sample code of the paging event looks like:

    protected void GridView2_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        GridView gvTemp = (GridView)sender;
        gvUniqueID = gvTemp.UniqueID;
        gvNewPageIndex = e.NewPageIndex;
        GridView1.DataBind();
    }

    Here, we have identified the run time unique ID of the child grid which needs paging along with the new page number. We are going to use these variable values in the RowDataBound event of the parent grid, as below:

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        ........................
        //Find Child GridView control
        GridView gv = new GridView();
        gv = (GridView)row.FindControl("GridView2");
        //Check if any additional conditions (Paging, Sorting, Editing, etc) 
        //to be applied on child GridView
        if (gv.UniqueID == gvUniqueID)
        {
            gv.PageIndex = gvNewPageIndex;
            gv.EditIndex = gvEditIndex;
            //Check if Sorting used
            if (gvSortExpr != string.Empty)
            {
                GetSortDirection();
                strSort = " ORDER BY " + string.Format("{0} {1}", gvSortExpr, gvSortDir);
            }
            //Expand the Child grid
            ClientScript.RegisterStartupScript(GetType(), "Expand", 
                "<script language="javascript"></script>");
        }
        ..........................
    }

The remaining actions (Sorting/Edit/Update/Delete) can also be handled similarly to paging. Refer to the source code attached above.

Conclusion

The GridView has more features compared to the DataGrid, which will make it easier to code, and also, we can include HTML tags in between for more flexibility.

License

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

Share

About the Author

Veera V Satya N Kanithi
Architect
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
Generalnice work [modified] Pin
MrKhalid21-Jun-09 8:55
memberMrKhalid21-Jun-09 8:55 
GeneralChildgrid Sort Pin
doran_doran7-Jun-09 17:57
memberdoran_doran7-Jun-09 17:57 
GeneralExpand/Collapse all Pin
Member 28890133-Jun-09 18:40
memberMember 28890133-Jun-09 18:40 
GeneralRe: Expand/Collapse all Pin
inetfly12326-Aug-09 4:45
memberinetfly12326-Aug-09 4:45 
GeneralRe: Expand/Collapse all Pin
doran_doran17-Sep-09 2:52
memberdoran_doran17-Sep-09 2:52 
GeneralRe: Expand/Collapse all [modified] Pin
doran_doran9-Oct-09 5:15
memberdoran_doran9-Oct-09 5:15 
QuestionEditable Nested GridView Pin
Member 28890131-Jun-09 16:01
memberMember 28890131-Jun-09 16:01 
Generalyes,like this message! Pin
molan liu22-May-09 7:43
membermolan liu22-May-09 7:43 
Generalthird grid collapses Pin
kdsv23-Mar-09 9:23
memberkdsv23-Mar-09 9:23 
QuestionRe: third grid collapses Pin
Palenaka1158-Jun-09 8:03
memberPalenaka1158-Jun-09 8:03 
Questionduring the edit click mode of gridview3 then the grids getting collapsed Pin
Member 424944011-Feb-09 20:31
memberMember 424944011-Feb-09 20:31 
Generalwhen using dropdownlist in nested gridview nested gridview is closed how can i solve this problem Pin
gm88812-Jan-09 18:49
membergm88812-Jan-09 18:49 
Questionneed help, PageIndexChanging & EditIndex for GridView2 Pin
alaaomer12314-Nov-08 12:23
memberalaaomer12314-Nov-08 12:23 
GeneralProblem with ajax update panel Pin
saeed abaskhah30-Oct-08 7:44
membersaeed abaskhah30-Oct-08 7:44 
GeneralRe: Problem with ajax update panel Pin
Member 425847121-Sep-09 9:37
memberMember 425847121-Sep-09 9:37 
GeneralIE7 Pin
db11828-Jul-08 6:35
memberdb11828-Jul-08 6:35 
QuestionProblem with third gridview using ie6 Pin
chakosci13-Jul-08 17:19
memberchakosci13-Jul-08 17:19 
GeneralVB version Pin
Member 173386922-Feb-08 6:24
memberMember 173386922-Feb-08 6:24 
GeneralRe: VB version Pin
jameshhood13-Apr-09 5:22
memberjameshhood13-Apr-09 5:22 
GeneralProblem in pageindexchanging event in third grid Pin
bamagrad11-Feb-08 10:43
memberbamagrad11-Feb-08 10:43 
GeneralRe: Problem in pageindexchanging event in third grid Pin
span605409-Mar-08 12:40
memberspan605409-Mar-08 12:40 
GeneralAccess Datasource Pin
jeff kennedy28-Jan-08 6:32
memberjeff kennedy28-Jan-08 6:32 
GeneralRe: Access Datasource Pin
jeff kennedy28-Jan-08 7:43
memberjeff kennedy28-Jan-08 7:43 
GeneralI need some help with adding Additional Nested Gridviews to the example in this article. Pin
bamagrad27-Jan-08 10:49
memberbamagrad27-Jan-08 10:49 
GeneralRe: I need some help with adding Additional Nested Gridviews to the example in this article. Pin
bamagrad11-Feb-08 11:10
memberbamagrad11-Feb-08 11:10 
GeneralRe: I need some help with adding Additional Nested Gridviews to the example in this article. Pin
span605409-Mar-08 12:48
memberspan605409-Mar-08 12:48 
GeneralChild grid view gets closed when paging is done Pin
Member 41212499-Jan-08 21:58
memberMember 41212499-Jan-08 21:58 
GeneralRe: Child grid view gets closed when paging is done Pin
Satya Kanithi10-Jan-08 5:01
memberSatya Kanithi10-Jan-08 5:01 
GeneralRe: Child grid view gets closed when paging is done Pin
span605409-Mar-08 12:46
memberspan605409-Mar-08 12:46 
GeneralRe: Child grid view gets closed when paging is done Pin
Marlin719-Jun-09 5:49
memberMarlin719-Jun-09 5:49 
AnswerRe: Child grid view gets closed when paging is done Pin
plcasey11-Aug-10 17:37
memberplcasey11-Aug-10 17:37 
GeneralExtra space for child grid column in parent grid Pin
Member 471192020-Dec-07 2:59
memberMember 471192020-Dec-07 2:59 
QuestionFixed Header [modified] Pin
rpack197930-Oct-07 3:51
memberrpack197930-Oct-07 3:51 
AnswerRe: Fixed Header Pin
Satya Kanithi30-Oct-07 4:20
memberSatya Kanithi30-Oct-07 4:20 
QuestionAjax enabled Pin
jones7415-Oct-07 15:31
memberjones7415-Oct-07 15:31 
GeneralRe: Ajax enabled Pin
Satya Kanithi18-Oct-07 8:38
memberSatya Kanithi18-Oct-07 8:38 
QuestionHow to display header and footer for gridview2 when there is no data related to that... Pin
Saurabh Tripathi14-Oct-07 22:17
memberSaurabh Tripathi14-Oct-07 22:17 
AnswerRe: How to display header and footer for gridview2 when there is no data related to that... Pin
Satya Kanithi15-Oct-07 4:18
memberSatya Kanithi15-Oct-07 4:18 
GeneralNice!! Pin
wishpl2-Oct-07 20:53
memberwishpl2-Oct-07 20:53 
GeneralEmpty row shows in Firefox Pin
asianvato24-Sep-07 7:43
memberasianvato24-Sep-07 7:43 
QuestionGridview2 - not recognized Pin
Lee Helzer19-Sep-07 10:39
memberLee Helzer19-Sep-07 10:39 
AnswerRe: Gridview2 - not recognized Pin
Lee Helzer19-Sep-07 19:50
memberLee Helzer19-Sep-07 19:50 
GeneralGREAT Pin
abhijit.coder17-Sep-07 21:07
memberabhijit.coder17-Sep-07 21:07 
GeneralGood job!!! Pin
VenAliens12-Sep-07 12:03
memberVenAliens12-Sep-07 12:03 
QuestionProblem on getting the values from Thir Gridview Pin
ihsanps7-Sep-07 0:16
memberihsanps7-Sep-07 0:16 
GeneralNice Work! Pin
treesprite5-Sep-07 8:40
membertreesprite5-Sep-07 8:40 
GeneralAddtional Function Pin
hallie2-Sep-07 16:53
memberhallie2-Sep-07 16:53 
GeneralNested gridview Pin
JohnnyHax27-Aug-07 17:37
memberJohnnyHax27-Aug-07 17:37 
GeneralEditable Nested GridView Pin
michaeltaylor27-Aug-07 5:29
membermichaeltaylor27-Aug-07 5:29 
AnswerRe: Editable Nested GridView Pin
Satya Kanithi27-Aug-07 6:16
memberSatya Kanithi27-Aug-07 6:16 

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 | Terms of Use | Mobile
Web03 | 2.8.150819.1 | Last Updated 17 Aug 2007
Article Copyright 2007 by Veera V Satya N Kanithi
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid