Click Here to Install Silverlight*
IndiaChange|All Microsoft Sites
MSDN
|Developer Centers|Library|Downloads|How To Buy|Subscribers|My MSDN
 
Master Detail DataGrid in ASP.NET
By Saravana
 
Article Posted: June 03, 2003
 

Introduction

Many times we require to display data in master-detail format. ASP.NET controls like DataGrid and DataList can be easily used for this purpose. In this article we will see how we can create Master detail grid using DataGrid.

The default model for selecting rows in the grid is for us to add a Select button (actually, a LinkButton control or a button column) whose CommandName property is set to "Select." When the button is clicked, the DataGrid control receives the Itemcommand and in that event handler you can write code to display Details records in Detail DataGrid.

Not everyone likes having an explicit Select button, and a common question is how to implement the feature where users can click anywhere in a grid row to select it. The solution is to perform a kind of sleight-of-hand in the grid. You add the Select LinkButton or buttoncolumn control as normal. Users can still use it, or you can hide it. In either event, you then inject some client script into the page that effectively duplicates the functionality of the Select button for the row as a whole. We will see how we can create this type of Master Details DataGrid in this article.

Master Detail DataGrid With Select Button

In this Master Detail DataGrid, we have two DataGrids. First DataGrid consists of four Boundcolumn and one Buttoncolumn to show Master Records. Buttoncolumn is to select the master record so that corresponding detail records can be shown in other DataGrid. Next DataGrid consists of three Boundcolumn to show Detail records. This example uses Customers and Orders table from Northwind DataBase.

Following is the markup of the web form:

<asp:DataGrid id="DataGrid1" style="Z-INDEX: 101; LEFT: 8px" runat="server" PagerStyle-Visible="False" PageSize="10" ItemStyle-CssClass="tableItem" HeaderStyle-CssClass="tableHeader" HeaderStyle-BackColor="#aaaadd" BorderColor="black" SelectedItemStyle-BackColor=#99ccff AutoGenerateColumns="False" DataKeyField="CustomerID">

    <Columns>

        <asp:boundcolumn ItemStyle-Width="100" runat="server" DataField="CustomerID" HeaderText="Customer ID" >
        </asp:boundcolumn>

       <asp:boundcolumn ItemStyle-Width="100" runat="server" DataField="CompanyName" HeaderText="Company Name">
        </asp:boundcolumn>

       
        <asp:boundcolumn ItemStyle-Width="100" runat="server" DataField="ContactName" HeaderText="Contact Name">
        </asp:boundcolumn>

      
        <asp:boundcolumn ItemStyle-Width="100" runat="server" DataField="Address" HeaderText="Address">
        </asp:boundcolumn>

       <asp:ButtonColumn ItemStyle-Width="100" runat="server" text="Show Details" visible="True" HeaderText="Select">
        </asp:ButtonColumn>

    </Columns>

</asp:DataGrid>

<asp:DataGrid id="Datagrid2" style="Z-INDEX: 101; LEFT: 8px" runat="server" PagerStyle-Visible="False" PageSize="10" ItemStyle-CssClass="tableItem" HeaderStyle-CssClass="tableHeader" HeaderStyle-BackColor="#aaaadd" BorderColor="black" AutoGenerateColumns="False">

   <Columns>

       <asp:boundcolumn ItemStyle-Width="100" runat="server" DataField="CustomerID" HeaderText="Customer ID" >
       </asp:boundcolumn>


       <asp:boundcolumn ItemStyle-Width="100" runat="server" DataField="OrderID" HeaderText="Order ID" >
       </asp:boundcolumn>

       <asp:boundcolumn ItemStyle-Width="100" runat="server" DataField="OrderDate" HeaderText="Order Date" >
       </asp:boundcolumn>

   </Columns>

</asp:DataGrid>

It is fairly straight forward, although we are setting a number of properties of the master grid and using templates to control the appearance of the grid. The key points to notice in the master grid are that we have implemented the DataGrid1_ItemCommand method to raise the ItemCommand event. This event, not surprisingly, is raised when an item in the datagrid is selected (i.e. when Select button is pressed). We have also implemented a button column with text of "Show Details" so that we can select a particular row of the datagrid. We have also set the DataKeyField property to "CustomerID". The is the key common to both tables and will be accessible to the details datagrid upon selection of a row in the master datagrid. The details datagrid contains only cosmetic property settings and templates.

Master DataGrid is populated in Page_Load, Page_Load event handler is show below

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 

     If Not IsPostBack Then 

            Dim connstr As String = "Integrated Security=SSPI;Initial Catalog=Northwind;Data Source=.\NetSDK"
           
Dim cnn As New SqlConnection(connstr)

            Dim da As New SqlDataAdapter("select top 5 customerid, companyname, contactname, address from customers", cnn)
            Dim ds As New DataSet()
            da.Fill(ds, "customers")
            DataGrid1.DataSource = ds
            DataGrid1.DataBind()
      End If
End Sub

When the user press Select Button in Master DataGrid. Item_Command event is raised. Following code show how this event handler look like:

Private Sub DataGrid1_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles DataGrid1.ItemCommand 
        Dim connstr As String = "Integrated Security=SSPI;Initial Catalog=Northwind;Data Source=.\NetSDK"
        Dim cnn As New SqlConnection(connstr)
        Dim da As New SqlDataAdapter("select CustomerID,orderid,orderdate from orders where customerid='" & DataGrid1.DataKeys(e.Item.ItemIndex) & "'", cnn)
        DataGrid1.SelectedIndex = e.Item.ItemIndex()
        Dim ds As New DataSet()
        da.Fill(ds, "orders")
        Datagrid2.DataSource = ds
        Datagrid2.DataBind()
End Sub

Master Details Grid with select button will look like this:

Master Detail DataGrid Without Select Button

The default model of Master Detail Grid which we had seen previously uses a Select Button (ButtonColumn) for selecting rows in the grid .When the button is clicked, the DataGrid control receives the ItemCommand and in that event handler we are able to write code for populating Detail Grid with Details records.

Not everyone likes having an explicit Select button, and a common question is how to implement the feature where users can click anywhere in a grid row to select it. The solution is to perform a kind of sleight-of-hand in the grid. You add the Select LinkButton control as normal. Users can still use it, or you can hide it. In either event, you then inject some client script into the page that effectively duplicates the functionality of the Select button for the row as a whole.

The example below shows how. In the grid's ItemDataBound handler, first make sure that you are not in the header, footer, or pager. Then get a reference to the Select button, which in this instance is assumed to be the first control in the fourth cell. You then call a little-known method called GetPostBackClientEvent . This method returns the name of the PostBack call for the designated control. In other words, if you pass in a reference to a Button control, it returns the name of the client function call that will perform the PostBack.

Finally, you assign the client-side method to the item itself. When the grid renders, it renders as an HTML table. By assigning the method to the item, it is the equivalent of adding client-side code to each row (<TR> element) in the table. The grid's Item object does not directly support a way to assign client code to it, but you can do that by using its Attributes collection, which passes anything you assign to it through to the browser. ItemDataBound handler is shown below:

Private Sub DataGrid1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemDataBound

       
Dim itemType As ListItemType = e.Item.ItemType

        If ((itemType = ListItemType.Pager) Or _
           (itemType = ListItemType.Header) Or _
           (itemType = ListItemType.Footer)) Then
            Return
        Else
            Dim button As Control = _
               CType(e.Item.Cells(4).Controls(0), Control)
            e.Item.Attributes("onclick") = _
               Page.GetPostBackClientEvent(button, "")
        End If

End Sub

Other than the above change, we need to make visible of that select button to false. These are the two changes which we need to do in the previous example to avoid select button in Master grid. Now the screen will look like this:

When we click anywhere inside a row in Master DataGrid, that row is selected. Depending upon the selected row corresponding details record is populated in Details DataGrid. One small disadvantage of this technique is that it adds somewhat to the stream rendered to the browser, and it adds information for each row to view state.

 
 

©2009 Microsoft Corporation. All rights reserved. Contact Us |Terms of Use |Trademarks |Privacy Statement
Microsoft