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