Cascade GridView In ASP.NET

Hi Guys,

Have you ever used cascading GridView (GridView inside another GridView) ? I recently got a chance to work on an project where I have to display data in Master Detail relationship so I thought why don’t I used GridView to display detail data with displaying data along with Master data so tried to use Gridview inside a parent GridView.

Example:

In SQL create two tables to maintain the parent child relationship(Primary Foreign Key relationship). I am giving you my code what I used for my purpose.

CREATE TABLE dbo.SalesHeader
(
     InvoiceNo            VARCHAR(10)
     , InvoiceDate        DATETIME
     , CustomerName        VARCHAR(50)
     , TotalAmount        NUMERIC(10,2)     
)     

CREATE TABLE dbo.SalesDetail
(
     InvoiceNo        VARCHAR(10)
     , Item            VARCHAR(10)
     , Qty            INT
     , Price        NUMERIC(10,2)
     , Amount AS (Qty*Price)
)   

Put some data from front or backend so that you can display record in this sample. InvoiceNo field is the 
PrimaryKey in SalesHeader table which acts as ForeignKey in SalesDetail table.

UI Design:

In your page drag and drop a Master GridView which will display your Header level information and a 
Detail/Child GridView would be inside this Master GridView which will display the Detail level of 
information for the selected record in Master GridView.I have used 2 Icons Plus and Minus to expand and collapse
the Header and Detail recrods.
Below is the code.


<asp:GridView ID="gvParent" runat="server" AutoGenerateColumns="False" CellPadding="4"
            Width="100%" OnRowDataBound="gvParent_RowDataBound" OnRowCommand="gvParent_RowCommand"
            ForeColor="Black" BackColor="#CCCCCC" BorderColor="#999999" BorderStyle="Solid"
            BorderWidth="3px" CellSpacing="2">
            <FooterStyle BackColor="#CCCCCC" />
            <HeaderStyle BackColor="Black" Font-Bold="True" ForeColor="White" />
            <Columns>
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:ImageButton ID="btnImage" runat="server" ImageUrl="~/Images/plus.gif" CommandName="expand" />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="InvoiceNo" HeaderText="Invoice No."></asp:BoundField>
                <asp:BoundField DataField="InvoiceDate" HeaderText="Invoice Date"></asp:BoundField>
                <asp:BoundField DataField="CustomerName" HeaderText="Customer Name"></asp:BoundField>
                <asp:BoundField DataField="TotalAmount" HeaderText="Total Amount"></asp:BoundField>
                <asp:TemplateField>
                    <ItemTemplate>
                        </td></tr>
                        <tr>
                            <td>
                            </td>
                            <td colspan="4">
                                <asp:GridView ID="gvChild" runat="server" Width="100%" Visible="False" AutoGenerateColumns="False"
                                    DataSource='<%# GetChildRelation(Container.DataItem,"Relation") %>' BackColor="White"
                                    BorderColor="#999999" BorderStyle="Solid" BorderWidth="1px" CellPadding="3" ForeColor="Black"
                                    GridLines="Vertical">
                                    <AlternatingRowStyle BackColor="#CCCCCC" />
                                    <Columns>
                                        <asp:BoundField DataField="Item" HeaderText="Item"></asp:BoundField>
                                        <asp:BoundField DataField="Qty" HeaderText="Quantity"></asp:BoundField>
                                        <asp:BoundField DataField="Price" HeaderText="Price"></asp:BoundField>
                                        <asp:BoundField DataField="Amount" HeaderText="Total"></asp:BoundField>
                                    </Columns>
                                    <FooterStyle BackColor="#CCCCCC" />
                                    <HeaderStyle BackColor="Black" Font-Bold="True" ForeColor="White" />
                                    <PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
                                    <SelectedRowStyle BackColor="#000099" Font-Bold="True" ForeColor="White" />
                                    <SortedAscendingCellStyle BackColor="#F1F1F1" />
                                    <SortedAscendingHeaderStyle BackColor="#808080" />
                                    <SortedDescendingCellStyle BackColor="#CAC9C9" />
                                    <SortedDescendingHeaderStyle BackColor="#383838" />
                                </asp:GridView>
                            </td>
                        </tr>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
            <PagerStyle BackColor="#CCCCCC" ForeColor="Black" HorizontalAlign="Left" />
            <RowStyle BackColor="White" />
            <SelectedRowStyle BackColor="#000099" Font-Bold="True" ForeColor="White" />
            <SortedAscendingCellStyle BackColor="#F1F1F1" />
            <SortedAscendingHeaderStyle BackColor="#808080" />
            <SortedDescendingCellStyle BackColor="#CAC9C9" />
            <SortedDescendingHeaderStyle BackColor="#383838" />
        </asp:GridView>

Code behind:

    // Display Header records at page load event.
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            DataSet ds = new DataSet();            
            ds = GetData();
            ds.Tables[0].TableName = "Parent";
            ds.Tables[1].TableName = "Child";
            DataRelation dr = new DataRelation("Relation", ds.Tables["Parent"].Columns["InvoiceNo"], ds.Tables["Child"].Columns["InvoiceNo"], false);
            dr.Nested = true;
            ds.Relations.Add(dr);
            gvParent.DataSource = ds;
            gvParent.DataMember = "Parent";
            gvParent.DataBind();
        }
    }
    // Define the ForeignKey relationship among the records retrieved
    protected DataView GetChildRelation(object pDataItem, string pRelation)
    {
        DataRowView pvoDataRowView;
        pvoDataRowView = (DataRowView)pDataItem;
        if (pvoDataRowView != null)
            return pvoDataRowView.CreateChildView(pRelation);
        else
            return null;
    }
    // Check whether comment fired is for Expand or Collapse(Hide/Show detail record)
    protected void gvParent_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "expand")
        {
            int pviIndex;
            pviIndex = Convert.ToInt16(e.CommandArgument.ToString());
            ImageButton btn = new ImageButton();
            btn = (ImageButton)gvParent.Rows[pviIndex].FindControl("btnImage");
            if (btn.ImageUrl.ToLower().Contains("plus.gif"))
            {
                btn.ImageUrl = "images/minus.gif";
                ((GridView)gvParent.Rows[pviIndex].FindControl("gvChild")).Visible = true;
            }
            else
            {
                btn.ImageUrl = "images/plus.gif";
                ((GridView)gvParent.Rows[pviIndex].FindControl("gvChild")).Visible = false;
            }
        }
    }
    // Get Invoice No whose detail has to be shown.
    protected void gvParent_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            ImageButton btn = new ImageButton();
            btn = (ImageButton)e.Row.Cells[0].FindControl("btnImage");
            btn.CommandArgument = e.Row.RowIndex.ToString();
        }
    }

   //ADO.NET code to retrieve the Header and Detail records from Source tables.
    private DataSet GetData()
    {
        DataSet ds = new DataSet();
        SqlConnection con = new SqlConnection(ConnectionString);
        con.Open();
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = con;
        cmd.CommandText = @"BEGIN SELECT InvoiceNo, CONVERT(VARCHAR, InvoiceDate, 106) AS InvoiceDate, CustomerName, TotalAmount from SalesHeader; SELECT InvoiceNo, Item, Qty, Price, Amount FROM SalesDetail END";
        cmd.CommandType = CommandType.Text;
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        da.Fill(ds);
        con.Close();
        return ds;
    }    
Output:

gridview

gridview

Summary: I tried to explain in very simple way possible however if any of you guys having any issue in understanding drop a comment at bottom of article with your query. Feedback and comments are most welcome.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s