Ask the DotNetJunkies : Building a Master/Detail DataGrid Part II
By Doug Seven
Published: 10/10/2001
Reader Level: Intermediate
Rated: 5.00 by 2 member(s).
Tell a Friend
Rate this Article
Printable Version
Discuss in the Forums

Question:

Building a Master/Detail DataGrid - Great Article! How would a template column be created and included in the DataGrid that appears in the Orders column.
GfWeis

The Answer:

Well, first off...thanks for the compliment. Now, let's cut to the chase. What you are asking, adding a TemplateColumn to an embedded DataGrid, can certainly be done. We are going to take a slightly different approach for this however. In this tutorial I will show you how to embed a DataGrid in a DataGrid, with a TemplateColumn in the embedded DataGrid. The design for the embedded DataGrid will actually be done in the Web Form, and we will call a method in our code behind class to populate the embedded DataGrid.

Let's Get It On

We will demonstrate building a master/detail DataGrid using the Northwind Customers and Orders tables. The sample code download has all of the sample code is in C# and Visual Basic .NET.

First, lets build the Web form user interface. For this we will use a DataGrid with BoundColumns and TemplateColumns, similar to the one in the first article. The result will look like this:

[Run Sample]

From the screenshot you can see that we have three columns, ID, Customer, and Orders. The Orders column has an embedded DataGrid, which is made up of two columns, Order ID and a TemplateColumn displaying the order infomration..

Here is the Web Form code:

<%@ Page language="c#" Inherits="MasterDetail.CustomerOrderDataGrid" EnableViewState="False" %>
<HTML>
<body
style="font: x-small Verdana, Arial, sans-serif;">
<!-- Begin Web Form -->
<form id="CustomerOrderDataGrid" method="post" runat="server">
  <p><a href="/DayOfDotNet/">Parent Directory</a></p>

  <!-- Begin DataGrid -->
  <asp:DataGrid id="CustomerDataGrid" runat="server"
    AutoGenerateColumns="False"
    CellPadding="2" CellSpacing="0"
    Font-Names="Verdana, Arial, sans-serif"
    BorderColor="Black" BorderWidth="1"
    GridLines="Horizontal"
    OnItemDataBound="CustomerDataGrid_OnItemDataBound">

    <HeaderStyle
      Font-Bold="True" Font-Size="small"
      Font-Name="Arial"
      BackColor="Maroon" ForeColor="White" />

    <ItemStyle Font-Size="x-small" />

    <AlternatingItemStyle BackColor="Tan" />

    <Columns>

      <asp:HyperLinkColumn
        DataTextField="CustomerID"
        DataNavigateUrlField="CustomerID"
        DataNavigateUrlFormatString="OrderDetailDataGrid.aspx?customerid={0}"
        HeaderText="ID"
        ItemStyle-VerticalAlign="Top" />

      <asp:TemplateColumn ItemStyle-VerticalAlign="Top" HeaderText="Customer">
        <ItemTemplate>
          <b><%# DataBinder.Eval(Container.DataItem, "CompanyName") %></b><br>
          <%# DataBinder.Eval(Container.DataItem, "Address" ) %><br>
          <%# DataBinder.Eval(Container.DataItem, "City" ) %>,
          <%# DataBinder.Eval(Container.DataItem, "Region") %>
          <%# DataBinder.Eval(Container.DataItem, "PostalCode" ) %><br>
          <br>
          <%# DataBinder.Eval(Container.DataItem, "ContactName" ) %><br>
          <%# DataBinder.Eval(Container.DataItem, "ContactTitle" ) %><br>
          <%# DataBinder.Eval(Container.DataItem, "Phone" ) %>
        </ItemTemplate>
      </asp:TemplateColumn>

      <asp:TemplateColumn
        ItemStyle-VerticalAlign="Top"
        HeaderText="Orders"
        ItemStyle-Width="100%">

  
      <ItemTemplate>

  
        <asp:DataGrid runat="server"
            AutogenerateColumns="False"
            Width="100%"
            GridLines="Horizontal"
            BorderColor="Black"
            BorderWidth="1"
            Font-Name="Verdana"
            Font-Size="x-small"
            DataSource='<%# getOrdersDataSource( (string)DataBinder.Eval(Container.DataItem, "CustomerID") ) %>'>

  
          <HeaderStyle
              BackColor="Black"
              ForeColor="White"
              Font-Bold="True" />

  
          <ItemStyle BackColor="White" />

  
          <AlternatingItemStyle BackColor="Silver" />

  
          <Columns>
              <asp:BoundColumn DataField="OrderID" HeaderText="Order ID" />
                <asp:TemplateColumn>
                  <ItemTemplate>
                    <b>Order Date: </b>
                    <%# DataBinder.Eval(Container.DataItem, "OrderDate", "{0:D}" ) %>
                    <br>
                    <b>Shipped Date: </b>
                    <%# DataBinder.Eval(Container.DataItem, "OrderDate", "{0:D}" ) %>
                    <br>
                    <b>Required Date: </b>
                    <%# DataBinder.Eval(Container.DataItem, "OrderDate", "{0:D}" ) %>
                    <br>
                </ItemTemplate>
              </asp:TemplateColumn>
            </Columns>
          </asp:DataGrid>
        </ItemTemplate>
      </asp:TemplateColumn>
    </Columns>
  </asp:DataGrid>
<!-- End DataGrid -->
</form>
<!-- End Web Form -->
</body>
</HTML>

In the thrid column, a TemplateColumn, we have a DataGrid - this is the embedded DataGrid. In this example we have defined the two columns of the embeded DataGrid as a BoundColumn and a TemplateColumn. In the TemplateColumn we define an ItemTemplate, which will control how each row in this column is rendered. We use the DataBinder to render specified columns from our data source.

The DataSouce property of the embedded DataGrid points to a method that we will define in the code behind class.

Break It Down

In the code behind class for the Web Form we will do a couple of things: bind the CustomerDataGrid server control to the Customers table from the Northwind database and expose a method to get the DataSource for the embedded DataGrid.

using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace
MasterDetail
{
  public class CustomerOrderDataGrid : System.Web.UI.Page
  {
    protected DataGrid CustomerDataGrid;
    private DataSet ds = new DataSet();
  
    private void Page_Load(object sender, System.EventArgs e)
    {
      if(!Page.IsPostBack)
      {
        BindData();
      }
    }

    private void BindData()
    {
      string sqlStmt = "SELECT * FROM Customers; SELECT * FROM Orders";
      string conString = "server=localhost;database=Northwind;uid=sa;pwd=;";
  
      SqlDataAdapter sda = new SqlDataAdapter(sqlStmt, conString);
  
      sda.Fill(ds);
      ds.Tables[0].TableName = "Customers";
      ds.Tables[1].TableName = "Orders";
  
      CustomerDataGrid.DataSource = ds.Tables["Customers"];
      CustomerDataGrid.DataBind();
    }

    protected DataView getOrdersDataSource(string _customerID)
    {
      DataView _orders = ds.Tables["Orders"].DefaultView;
      _orders.RowFilter = "CustomerID='" + _customerID + "'";
      return _orders;
    }
  }
}

In the SQL statement we select two result sets. When we invoke the data adapter's Fill() method this will create two DataTables, one for each result set. For organizational (and anal retentive) purposes, we set the TableName property of each of the DataTables, and bind the CustomerDataGrid.

Notice, we declared the DataSet (ds) at the class-level. This will give us access to the DataSet from the getOrdersDataSource() method. In the getOrdersDataSource() method we need to create a DataView that is the default view of the Orders DataTable from the DataSet. Then we use the DataView.RowFilter property to filter out all the records except records in the Orders DataTable that have the same CustomerID value as the CustomerID for the current row (the value passed into the method from the Web Form).

Summary

In this tutorial we looked at another way to embed a DataGrid a parent DataGrid...a master/detail DataGrid. In this tutorial we defined the DataGrid in the Web Form, including defining a TemplateColumn to use for custom layout. This method of embedding a DataGrid is much less complex, interms of code, and just as effective.



Marketplace
(Sponsored Links)
What are the green links?
   



 
Copyright © 2007 CMP Tech LLC |
Privacy Policy (4/10/06) | Your California Privacy Rights (4/10/06) | Terms of Service | Advertising Info | About Us | Help