Click here to Skip to main content
15,881,092 members
Articles / Web Development / ASP.NET

Hierarchical GridView Control Using AJAX

Rate me:
Please Sign up or sign in to vote.
2.69/5 (14 votes)
4 Mar 2010CPOL3 min read 66.5K   3.5K   13   22
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.NET
<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.

XML
<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.

C#
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.

C#
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)


Written By
Web Developer
India India
I am working for Polaris Software Lab - USA

Comments and Discussions

 
QuestionConfuse in the Second object datasource Pin
Shivarajbk24-Jul-13 20:03
Shivarajbk24-Jul-13 20:03 
GeneralMy vote of 5 Pin
Shivarajbk22-Jul-13 23:58
Shivarajbk22-Jul-13 23:58 
GeneralRe: My vote of 5 Pin
Shivarajbk23-Jul-13 0:00
Shivarajbk23-Jul-13 0:00 
QuestionIE10 Pin
Sergey_New11-May-13 6:40
Sergey_New11-May-13 6:40 
QuestionPerfect- Thanks for the pointers on hirerachy grid Pin
santhosh196914-Sep-12 23:18
santhosh196914-Sep-12 23:18 
QuestionNested GridView with multiple childgrdis Pin
dilfizo2-Apr-12 1:52
dilfizo2-Apr-12 1:52 
QuestionLogin failed for user ''. The user is not associated with a trusted SQL Server connection. Pin
mistrybhumi9-Mar-12 0:51
mistrybhumi9-Mar-12 0:51 
GeneralRe: Login failed for user ''. The user is not associated with a trusted SQL Server connection. Pin
Ram Sagar Mourya7-Jul-12 1:31
Ram Sagar Mourya7-Jul-12 1:31 
you need to change the connection string in the web.config file.

from

C#
 <connectionStrings>
   <add name="NorthwindConnectionString" connectionString="Data Source=SAKTHIVELG-PC\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True"
     providerName="System.Data.SqlClient" />
</connectionStrings>


to

C#
<connectionStrings>
   <add name="NorthwindConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True"
     providerName="System.Data.SqlClient" />
</connectionStrings>

QuestionHide the empty column at the end of the grid Pin
Kris W6-Jul-11 7:10
Kris W6-Jul-11 7:10 
QuestionPopulating the Grid from Object Data Source Pin
jayaraj7917-Mar-11 12:00
jayaraj7917-Mar-11 12:00 
GeneralAdd one more level to this Pin
rahult1235-Oct-10 1:27
rahult1235-Oct-10 1:27 
GeneralRe: Add one more level to this Pin
Sakthivel Ganesan6-Oct-10 4:00
Sakthivel Ganesan6-Oct-10 4:00 
GeneralRe: Add one more level to this Pin
rahult1232-Nov-10 0:24
rahult1232-Nov-10 0:24 
GeneralMy vote of 3 Pin
coderaug12-Aug-10 18:19
coderaug12-Aug-10 18:19 
GeneralMy vote of 2 Pin
sg10005-Mar-10 0:15
sg10005-Mar-10 0:15 
GeneralRe: My vote of 2 Pin
Sakthivel Ganesan5-Mar-10 4:18
Sakthivel Ganesan5-Mar-10 4:18 
GeneralMy vote of 1 Pin
Md. Marufuzzaman21-Feb-10 17:52
professionalMd. Marufuzzaman21-Feb-10 17:52 
GeneralRe: My vote of 1 Pin
Sakthivel Ganesan5-Mar-10 4:19
Sakthivel Ganesan5-Mar-10 4:19 
GeneralMy vote of 2 Pin
gaurav_verma_mca21-Feb-10 17:44
gaurav_verma_mca21-Feb-10 17:44 
GeneralMy vote of 2 Pin
Dave Kreskowiak21-Feb-10 3:27
mveDave Kreskowiak21-Feb-10 3:27 
GeneralRe: My vote of 2 Pin
Sakthivel Ganesan5-Mar-10 4:19
Sakthivel Ganesan5-Mar-10 4:19 
GeneralMy vote of 3 Pin
Mycroft Holmes21-Feb-10 0:18
professionalMycroft Holmes21-Feb-10 0:18 

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

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