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

Hierarchical GridView Control Using AJAX

, 4 Mar 2010
Rate this:
Please Sign up or sign in to vote.
Explains how to create a hierarchical GridView control in ASP.NET using AJAX

Introduction

HierachicalGridViewImage_small.gif

This article explains about creating a hierarchical grid view control. I implemented this grid two years ago in a project. I thought of publishing it at that time itself, but couldn't as I didn't have enough time. I am publishing it now, amidst tight timelines. You can use this grid to display the data in a parent-child model. In this example, I have used only one child grid. Using this code, you could convert a child grid to a parent by creating more child grids under it.

Background

Two GridViews and two ObjectDataSources have been used in this project. The IDs of the GridViews are grdOrders and grdOrderDetails. SQL Express has been used as a back-end server and NorthWind is the database in this module. In this document, grdOrders is referred as the parent grid, and grdOrderDetails is referred as the child grid which is placed inside grdOrders. By default, the Visible property of the child grid would be false. The parent grid would display the Orders. When the user clicks on a particular row on the parent grid, the child grid would be visible with the Order Details data.

Using the Code

Here is the declaration of the ObjectDataSources that are used to pull the data from the business logic layer:

<asp:ObjectDataSource ID="objDataSourceID" 
                        runat="server" 
                        SelectMethod="GetOrders" 
                        EnablePaging="true" 
                        TypeName="clsGeneralFunctions" 
                        StartRowIndexParameterName="StartRowIndex" 
                        MaximumRowsParameterName="MaximumRows" 
                        SelectCountMethod="GetOrdersCount">
</asp:ObjectDataSource>

The above ObjectDataSource is used to pull the data from the business logic layer for the parent DataGrid. The StartRowIndexParameterName and MaximumRowsParameterName properties are used to pull only the records that are needed to be displayed on the current page. The SelectCountMethod property is used to pull the total number of records that the actual query is going to return, which is used to display the total number of pages on the grid depending on the PageSize property. When the user selects a particular page number on the grid, the ObjectDataSource would execute the GetOrders method which is assigned to the SelectMethod property. If the EnablePaging property set to False, then there is no use of the StartRowIndexParameterName and MaximumRowsParameterName properties, i.e., we cannot pull just the records that are needed to be displayed on the current page.

<asp:ObjectDataSource   ID="objOrderDetails" 
                           runat="server" 
                           SelectMethod="GetOrdersDetailsList" 
                           EnablePaging="true" 
                           TypeName="clsGeneralFunctions" 
                           SelectCountMethod="GetOrdersDetailsCount">
   <SelectParameters>
   <asp:Parameter Direction="Input" 
        Name="StartRowIndex" type="Int32" />
   <asp:Parameter Direction="Input" 
        Name="MaximumRows" type="Int32" />
   <asp:Parameter Direction="Input" 
        Name="OrderId" 
        DefaultValue="0" type="Int32" />
   </SelectParameters>
</asp:ObjectDataSource>

The above ObjectDataSource is used to pull data from the business logic layer for the child DataGrid based on the Order ID, which will come from the parent grid. When the user clicks on a particular order on the parent grid, the child grid would display the order details for the selected order. The above ObjectDataSource has an extra input parameter called OrderId which is used to pass the Order ID to the methods that are assigned to the SelectCountMethod and SelectMethod properties.

protected void grdOrders_RowDataBound(object sender, GridViewRowEventArgs e)
{{
    ImageButton imgBtn;

    if (e.Row.RowType == DataControlRowType.DataRow)
    {

        imgBtn = (ImageButton)(e.Row.FindControl("ImgBtn"));
        imgBtn.CommandArgument = e.Row.RowIndex.ToString();

        if (e.Row.Cells[0].Text == Session["OrderId"])
        {
            PlaceHolder objPH;
            objPH = (PlaceHolder)(e.Row.FindControl("objPHOrderDetails"));
            if (objPH != null)
                objPH.Visible = true;

            if (imgBtn.ImageUrl == "Include/images/gridplus.gif")
                imgBtn.ImageUrl = @"Include/images/gridminus.gif";
            else
                imgBtn.ImageUrl = @"Include/images/gridplus.gif";
        }
    }
}

When the rows are created on the GridView, the above RowDataBound event gets fired. The above event is used to set the GridView row number to the CommandArgument property of the ImageButton. This property would be used in the RowCommand event of parent grid which gets fired when the user clicks on the ImageButton on the parent grid.

protected void grdOrders_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName == "Expand")
    {
        ImageButton imgbtn;
        GridView gv = (GridView)(sender);
        Int32 rowIndex = Convert.ToInt32(e.CommandArgument.ToString());
        PlaceHolder objPH = 
          (PlaceHolder)(gv.Rows[rowIndex].FindControl("objPHOrderDetails"));
        ObjectDataSource objDS = 
          (ObjectDataSource)(gv.Rows[rowIndex].FindControl("objOrderDetails"));
        GridView objChildGrid = 
          (GridView)(gv.Rows[rowIndex].FindControl("grdOrderDetails"));
        imgbtn = (ImageButton)(gv.Rows[rowIndex].FindControl("ImgBtn"));

        objDS.SelectParameters["OrderId"].DefaultValue = 
                    gv.DataKeys[rowIndex][0].ToString();
        Session["OrderId"] = gv.DataKeys[rowIndex][0].ToString();

        if (imgbtn.ImageUrl == "Include/images/gridplus.gif")
        {
            imgbtn.ImageUrl = @"Include/images/gridminus.gif";
            if (objChildGrid != null)
            {
                if (objPH != null)
                    objPH.Visible = true;
                objChildGrid.Visible = true;
            }
        }
        else
        {
            if (objChildGrid != null)
            {
                imgbtn.ImageUrl = @"Include/images/gridplus.gif";
                if (objPH != null)
                    objPH.Visible = false;
                objChildGrid.Visible = false;
            }
        }
    }
}

The if condition (e.CommandName == "Expand") is used to verify whether the user clicked on the ImageButton or not. The value "Expand" has been set to the CommandName property of the ImageButton. When the user clicks on the ImageButton, we create objects for all the controls that are inside the parent grid control, passing the selected row, i.e., the Order ID, to the child data source which would pull all the order details records for the selected order. Once the data gets populated in the child data grid, we should change the image button plus(+) symbol to minus(-) and should set the Visible property of the child grid and the PlaceHolder to true. Next time, when the user clicks on the same row, the minus symbol should be changed to a plus symbol and set the Visible property of the child grid and PlaceHolder to false, which the else statement does.

Points of Interest

We learnt about a lot of new controls during this project as we were new to ASP.NET.

License

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

About the Author

Sakthivel Ganesan
Web Developer
India India
I am working for Polaris Software Lab - USA

Comments and Discussions

 
QuestionConfuse in the Second object datasource PinmemberShivarajbk24-Jul-13 20:03 
GeneralMy vote of 5 PinmemberShivarajbk22-Jul-13 23:58 
GeneralRe: My vote of 5 PinmemberShivarajbk23-Jul-13 0:00 
QuestionIE10 PinmemberSergey_New11-May-13 6:40 
QuestionPerfect- Thanks for the pointers on hirerachy grid Pinmembersanthosh196914-Sep-12 23:18 
QuestionNested GridView with multiple childgrdis Pinmemberdilfizo2-Apr-12 1:52 
QuestionLogin failed for user ''. The user is not associated with a trusted SQL Server connection. Pinmembermistrybhumi9-Mar-12 0:51 
GeneralRe: Login failed for user ''. The user is not associated with a trusted SQL Server connection. PinmemberRam Sagar Mourya7-Jul-12 1:31 
QuestionHide the empty column at the end of the grid PinmemberKris W6-Jul-11 7:10 
QuestionPopulating the Grid from Object Data Source Pinmemberjayaraj7917-Mar-11 12:00 
GeneralAdd one more level to this Pinmemberrahult1235-Oct-10 1:27 
GeneralRe: Add one more level to this PinmemberSakthivel Ganesan6-Oct-10 4:00 
GeneralRe: Add one more level to this Pinmemberrahult1232-Nov-10 0:24 
GeneralMy vote of 3 Pinmembercoderaug12-Aug-10 18:19 
GeneralMy vote of 2 Pinmembersaygin5-Mar-10 0:15 
GeneralRe: My vote of 2 PinmemberSakthivel Ganesan5-Mar-10 4:18 
GeneralMy vote of 1 PinmvpMd. Marufuzzaman21-Feb-10 17:52 
GeneralRe: My vote of 1 PinmemberSakthivel Ganesan5-Mar-10 4:19 
GeneralMy vote of 2 Pinmembergaurav_verma_mca21-Feb-10 17:44 
GeneralMy vote of 2 PinmvpDave Kreskowiak21-Feb-10 3:27 
GeneralRe: My vote of 2 PinmemberSakthivel Ganesan5-Mar-10 4:19 
GeneralMy vote of 3 PinmvpMycroft Holmes21-Feb-10 0:18 

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
Web02 | 2.8.140721.1 | Last Updated 5 Mar 2010
Article Copyright 2010 by Sakthivel Ganesan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid