Blogs

Paul Kimmel's Blog

Assembling an N-Nested ASPxGridView

     

I was standing on the surprisingly biting concrete at TechEd 2009 and a customer asked: “does your ASPxGridView support n-nesting?” My response was why, yes, yes it does. Unfortunately I didn’t have an example handy, but yesterday at the end of the day I whipped one up and the ASPX is provided here with some basic instructions as to how to create n-nesting.

To summarize, our ASPxGridView supports nesting. Add two or more grids to a page in design mode, wire each up to a data source, and then drag and drop the grids to be nested into the DetailRow template region and you are pretty much finished. N-nesting is supported as an almost completely no code solution. You do have to correlate the keys between the parent and child grids and set a property or two, but that’s it. (For the finished result see Figure 1.)

image
Figure 1: The run-time view of a grid nested three levels deep. 

Wiring up One Grid

There are two parts to grid nesting. The first part—wiring the grid to data—is the same for all grids in the nesting relationship. Each grid in the nesting relationship has to have a source for its data. For the example right click the Smart tag associated with an ASPxGridView and select Choose Data Source|New data source to run the data source wizard. The Configure Data Source wizard will walk you through building a connection string, selecting your data source (and designing a query), and wiring up the resultant data source to associated ASPxGridView.

batgirl
Figure 2: Batgirl gives away Batman’s secret identity. I am Batman! (What happens at TechEd stays at TechEd.)

Correlating Child and Parent Grids

The only programming you need to do is a line of code that correlates a parent grid to a child grid. When you ware walking through the Configure Data Source wizard for the child grids you need to complete an extra step. Parent and child relationships can be defined with joins or WHERE clauses. For the Configure Data Source wizard use the WHERE button on the Configure the Select Statement (see Figure 3) step to specify how data are correlated to the parent data. For example, Northwind.Customers is related Northwind.Orders by CustomerID. To nest Orders in Customers click the WHERE button when configuring the Orders table and configure a WHERE condition for the foreign key CustomerID of the Orders table (use Figure 4 as a visual guide).

image
Figure 3:  On the Configure the Select Statement click the WHERE button to correlate the parent grids with the child grids.

image
Figure 4: Configure a column that represents the implicit WHERE-clause join column for child data sets.

For the demo Orders is nested in the Customers grid and Order Details is nested in the Orders grid. You will need to configure a WHERE condition when configuring the data source for the Orders table and the Orders Detail table. The Column value (see Figure 4) needs to be the Foreign key for the child table. The Operator needs to be equal and the Source value of Session means the primary key will be stored in the Session.

Next you need to store the primary key of the parent table in Session. So when a parent row is expanded the nested grid knows what parent row is being displayed. For the example, Customers grid contains Orders and the Orders grid contains Order Details. The only code you need to write to make the basic nesting work is a BeforePerformDataSelect event handler for the Orders grid and Order Detail grid. In each of these events the sender argument represents the parent grid. Cast sender as an ASPxGridView and invoke the GetMasterRowKeyValue method. Store the result in Session using the column defined in the Add WHERE Clause dialog (see Listing 1).

Listing 1: BeforePerformDataSelect gets the key from the parent row and stores it for the child grid, correlating the parent and child grids.

protected void ASPxGridView2_BeforePerformDataSelect(object sender, EventArgs e)
{
  Session["CustomerID"] = ((ASPxGridView)sender).GetMasterRowKeyValue();
}


protected void ASPxGridView3_BeforePerformDataSelect(object sender, EventArgs e)
{
  Session["OrderID"] = ((ASPxGridView)sender).GetMasterRowKeyValue();
}

Completing the Nesting Effect

To complete the nesting effect select the second to the last grid. In our example, select the Orders grid. From the Smart tags menu select Edit Templates and pick the DetailRow template. Drag and drop the grid containing the Order Details into the grid containing Orders DetailRow template (shown in Figure 5). Repeat the process to drag the grid containing the Orders (which now also contains the Order Details grid) data into the DetailRow template for the Customers grid.

 

image 
Figure 5: The grid containing the Order Details data shown nested in the grid containing the Orders data.

Finally, for the Orders and Order Details grids set the SettingsDetail.IsDetailGrid to true. For the Customers and Orders grids set the SettingsDetail.ShowDetailRow property to true. (Listing 2 contains all of the ASPX for the demo). That’s pretty much all there is to it. To recap, you need to:

  • Correlate every child to its parent with a WHERE clause
  • Implement a BeforePerformDataSelect method to store the parent grid’s master key in Session based on the named-value specified in the Add WHERE Clause step of the data source wizard
  • Place each child grid in the DetailRow template of its parent
  • Each grid needs its own data source
  • Every grid that has a detail grid needs the SettingsDetail.ShowDetailRow to true
  • Every grid that is a detail grid needs the SettingsDetail.IsDetailGrid to true

Listing 2: THE ASPX  for this sample was all generated by the IDE and the Developer Express controls. Here it is.

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register assembly="DevExpress.Web.ASPxGridView.v9.1, Version=9.1.2.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" namespace="DevExpress.Web.ASPxGridView" tagprefix="dxwgv" %>
<%@ Register assembly="DevExpress.Web.ASPxEditors.v9.1, Version=9.1.2.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" namespace="DevExpress.Web.ASPxEditors" tagprefix="dxe" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
      <dxwgv:ASPxGridView ID="ASPxGridView1" runat="server"
        AutoGenerateColumns="False" DataSourceID="SqlDataSource1"
        KeyFieldName="CustomerID">
        <Templates>
          <DetailRow>
            <dxwgv:ASPxGridView ID="ASPxGridView2" runat="server"
              AutoGenerateColumns="False" DataSourceID="SqlDataSource2"
              KeyFieldName="OrderID"
              onbeforeperformdataselect="ASPxGridView2_BeforePerformDataSelect">
              <Templates>
                <DetailRow>
                  <dxwgv:ASPxGridView ID="ASPxGridView3" runat="server"
                    AutoGenerateColumns="False" DataSourceID="SqlDataSource3"
                    KeyFieldName="OrderID"
                    onbeforeperformdataselect="ASPxGridView3_BeforePerformDataSelect">
                    <Columns>
                      <dxwgv:GridViewDataTextColumn FieldName="OrderID" ReadOnly="True"
                        VisibleIndex="0">
                      </dxwgv:GridViewDataTextColumn>
                      <dxwgv:GridViewDataTextColumn FieldName="ProductID" ReadOnly="True"
                        VisibleIndex="1">
                      </dxwgv:GridViewDataTextColumn>
                      <dxwgv:GridViewDataTextColumn FieldName="UnitPrice" VisibleIndex="2">
                      </dxwgv:GridViewDataTextColumn>
                      <dxwgv:GridViewDataTextColumn FieldName="Quantity" VisibleIndex="3">
                      </dxwgv:GridViewDataTextColumn>
                      <dxwgv:GridViewDataTextColumn FieldName="Discount" VisibleIndex="4">
                      </dxwgv:GridViewDataTextColumn>
                    </Columns>
                  </dxwgv:ASPxGridView>
                </DetailRow>
              </Templates>
              <Columns>
                <dxwgv:GridViewDataTextColumn FieldName="OrderID" ReadOnly="True"
                  VisibleIndex="0">
                  <EditFormSettings Visible="False" />
                </dxwgv:GridViewDataTextColumn>
                <dxwgv:GridViewDataTextColumn FieldName="CustomerID" VisibleIndex="1">
                </dxwgv:GridViewDataTextColumn>
                <dxwgv:GridViewDataTextColumn FieldName="EmployeeID" VisibleIndex="2">
                </dxwgv:GridViewDataTextColumn>
                <dxwgv:GridViewDataDateColumn FieldName="OrderDate" VisibleIndex="3">
                </dxwgv:GridViewDataDateColumn>
                <dxwgv:GridViewDataDateColumn FieldName="RequiredDate" VisibleIndex="4">
                </dxwgv:GridViewDataDateColumn>
                <dxwgv:GridViewDataDateColumn FieldName="ShippedDate" VisibleIndex="5">
                </dxwgv:GridViewDataDateColumn>
                <dxwgv:GridViewDataTextColumn FieldName="ShipVia" VisibleIndex="6">
                </dxwgv:GridViewDataTextColumn>
                <dxwgv:GridViewDataTextColumn FieldName="Freight" VisibleIndex="7">
                </dxwgv:GridViewDataTextColumn>
                <dxwgv:GridViewDataTextColumn FieldName="ShipName" VisibleIndex="8">
                </dxwgv:GridViewDataTextColumn>
                <dxwgv:GridViewDataTextColumn FieldName="ShipAddress" VisibleIndex="9">
                </dxwgv:GridViewDataTextColumn>
                <dxwgv:GridViewDataTextColumn FieldName="ShipCity" VisibleIndex="10">
                </dxwgv:GridViewDataTextColumn>
                <dxwgv:GridViewDataTextColumn FieldName="ShipRegion" VisibleIndex="11">
                </dxwgv:GridViewDataTextColumn>
                <dxwgv:GridViewDataTextColumn FieldName="ShipPostalCode" VisibleIndex="12">
                </dxwgv:GridViewDataTextColumn>
                <dxwgv:GridViewDataTextColumn FieldName="ShipCountry" VisibleIndex="13">
                </dxwgv:GridViewDataTextColumn>
              </Columns>
              <SettingsDetail IsDetailGrid="True" />
              <SettingsDetail ShowDetailRow="True" />
            </dxwgv:ASPxGridView>
          </DetailRow>
        </Templates>
        <Columns>
          <dxwgv:GridViewDataTextColumn FieldName="CustomerID" ReadOnly="True"
            VisibleIndex="0">
          </dxwgv:GridViewDataTextColumn>
          <dxwgv:GridViewDataTextColumn FieldName="CompanyName" VisibleIndex="1">
          </dxwgv:GridViewDataTextColumn>
          <dxwgv:GridViewDataTextColumn FieldName="ContactName" VisibleIndex="2">
          </dxwgv:GridViewDataTextColumn>
          <dxwgv:GridViewDataTextColumn FieldName="ContactTitle" VisibleIndex="3">
          </dxwgv:GridViewDataTextColumn>
          <dxwgv:GridViewDataTextColumn FieldName="Address" VisibleIndex="4">
          </dxwgv:GridViewDataTextColumn>
          <dxwgv:GridViewDataTextColumn FieldName="City" VisibleIndex="5">
          </dxwgv:GridViewDataTextColumn>
          <dxwgv:GridViewDataTextColumn FieldName="Region" VisibleIndex="6">
          </dxwgv:GridViewDataTextColumn>
          <dxwgv:GridViewDataTextColumn FieldName="PostalCode" VisibleIndex="7">
          </dxwgv:GridViewDataTextColumn>
          <dxwgv:GridViewDataTextColumn FieldName="Country" VisibleIndex="8">
          </dxwgv:GridViewDataTextColumn>
          <dxwgv:GridViewDataTextColumn FieldName="Phone" VisibleIndex="9">
          </dxwgv:GridViewDataTextColumn>
          <dxwgv:GridViewDataTextColumn FieldName="Fax" VisibleIndex="10">
          </dxwgv:GridViewDataTextColumn>
        </Columns>
        <SettingsDetail ShowDetailRow="True" />
      </dxwgv:ASPxGridView>
      <asp:SqlDataSource ID="SqlDataSource1" runat="server"
        ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
        SelectCommand="SELECT * FROM [Customers]"></asp:SqlDataSource>
      <asp:SqlDataSource ID="SqlDataSource2" runat="server"
        ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
        SelectCommand="SELECT * FROM [Orders] WHERE ([CustomerID] = @CustomerID)">
        <SelectParameters>
          <asp:SessionParameter Name="CustomerID" SessionField="CustomerID"
            Type="String" />
        </SelectParameters>
      </asp:SqlDataSource>
      <asp:SqlDataSource ID="SqlDataSource3" runat="server"
        ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
        SelectCommand="SELECT * FROM [Order Details] WHERE ([OrderID] = @OrderID)">
        <SelectParameters>
          <asp:SessionParameter Name="OrderID" SessionField="OrderID" Type="Int32" />
        </SelectParameters>
      </asp:SqlDataSource>
    </div>
    </form>
</body>
</html>

Happy TechEd! Have a safe trip home.

Published May 14 2009, 12:35 AM by Paul Kimmel (DevExpress)
Bookmark and Share

Comments

 

google.com » Blog Archive » child id tags said:

Pingback from  google.com  » Blog Archive   » child id tags

May 14, 2009 6:37 AM
 

PaulK said:

So, writing is pretty egoless for me. I suppose if I were treated like a rock star, got the hot babes

May 18, 2009 12:08 AM
 

PaulK said:

So, writing is pretty egoless for me. I suppose if I were treated like a rock star, got the hot babes

May 18, 2009 10:44 AM
 

Kelsey Grammer said:

Is it me or did you steal my photograph for your book? ;-)

July 1, 2009 5:00 AM
 

BladeRaja said:

You refer to the session variable with an @ symbol preceding the foreign key.

In my devexpress setup (9.2.4), the @ doesnt get added in the SQL expression when I choose session value. Any help as to why this might be happening?

September 23, 2009 1:25 PM
 

Paul Thomassian said:

hi,

I have Visual studio 2008, and trying to make the example above, but SettingsDetail.ShowDetailRow is not showing in the properties. Do I need to install any add on to VS,

thank you

July 17, 2010 12:11 AM
More from DevExpress
Live Chat
Have a pre-sales question?
Need assistance with your evaluation?
We are here to help.
Chat is one of the many ways you can contact members of the DevExpress Team. We are available Monday-Friday between 8:30am and 5:00pm Pacific Time.
If you need additional product information, require pre-sales assistance, or want help with your order, write to us at info@devexpress.com or call us at
+1 (818) 844-3383.