|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis article presents how the This article provides a simple, easy, and clean solution for displaying data with multilevel master/detail relationships. This article also shows how the BackgroundI happened to work on an HRM system of a company where I had to display details of employees' log events. This was a three level master detail relationship. At the first level, I had to show all the employees of the company (in a Using the codeIn this particular demo version, I have used Northwind’s Pubs database. The tables Publishers, Titles, and Roysched have a three level master detail hierarchical relationship: each publisher has published multiple titles, and each title has multiple royalty schedules. There is a parent SelectCommand="SELECT [pub_id], pub_name], [city] FROM [publishers]";
I have removed the formatting code and explained the implementation of all three Parent GridViewThe parent <asp:GridView ID="ParentGridView" runat="server"
DataSourceID="ParentSqlDataSource"
AutoGenerateColumns="False"
DataKeyNames="pub_id"
OnRowEditing= "ParentGridView_OnRowEditing"
<Columns>
<asp:TemplateField HeaderText="PublisherID">
<ItemTemplate>
<asp:Label id="pubid_lbl" Runat="Server"
Text='<%# Eval("pub_id") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:Label id="name_lbl" Runat="Server"
Text='<%# Eval("pub_name") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="City">
<ItemTemplate>
<asp:Label id="city_lbl" Runat="Server"
Text='<%# Eval("city") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:Button ID="ViewChild_Button"
runat="server" Text="+" CommandName="Edit" />
</ItemTemplate>
<EditItemTemplate>
<asp:Button ID="CancelChild_Button"
runat="server" Text="-" CommandName="Cancel" />
*ChildGridView…will come here
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The event handling code for protected void ParentGridView_OnRowEditing(object sender,
GridViewEditEventArgs e)
{
int parent_index = e.NewEditIndex;
//to set the edit index of the Parent
//grid with that of the current row
ParentGridView.EditIndex = parent_index;
ParentGridView.DataBind();
//find the pubid_lbl containing pub_id in that
//particular row by using findcontrol method
GridViewRow row = ParentGridView.Rows[parent_index];
Label pub_id_lbl = (Label)row.FindControl("pubid_lbl");
//save pub_id and edit_index in session for childgridview's use
Session["PubID"] = Convert.ToInt32(pub_id_lbl.Text);
Session["ParentGridViewIndex"] = parent_index;
}
Child GridViewLet's take a look at the <SelectCommand="SELECT [title_id],[title], [type],[price]
FROM [titles] WHERE ([pub_id] = ?) ORDER BY [price]">
<SelectParameters>
<asp:SessionParameter Name="PubID" SessionField="PubID" Type="Int32" />
</SelectParameters>
The int parent_index =(int)Session["ParentGridViewIndex"];
GridViewRow parent_row = ParentGridView.Rows[parent_index];
We now have the row of GridView ChildGridiView =
(GridView)Parent_row.FindControl("ChildGridView");
The protected void ChildGridView_OnRowEditing(object sender,
GridViewEditEventArgs e)
{
//set the edit index of the child
//gridview with that of the current row
int parent_index =(int)Session["ParentGridViewIndex"];
GridViewRow parent_row = ParentGridView.Rows[parent_index];
GridView ChildGridiView =
(GridView)parent_row.FindControl("ChildGridView");
int child_index = e.NewEditIndex;
ChildGridiView.EditIndex = child_index;
ChildGridiView.DataBind();
//find the titleid_lbl in that particular
//row by using findcontrol method
GridViewRow child_row = ChildGridiView.Rows[child_index];
Label titleid_lbl = (Label)child_row.FindControl("titleid_lbl");
// save the title_id in session for grandchildgridview's use
Session["TitleID"] = titleid_lbl.Text;
}
Here is the aspx source of <asp:GridView ID="ChildGridView"
runat="server" AllowPaging="true" PageSize="4"
AutoGenerateColumns="false"
DataSourceID="ChildSqlDataSource"
OnRowEditing= "ChildGridView_OnRowEditing" >
<Columns>
<asp:TemplateField HeaderText="TitleID">
<ItemTemplate>
<asp:Label id="titleid_lbl" Runat="Server"
Text='<%# Eval("title_id") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Title">
<ItemTemplate>
<asp:Label id="title_lbl" Runat="Server"
Text='<%# Eval("title") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Type">
<ItemTemplate>
<asp:Label id="type_lbl" Runat="Server"
Text='<%# Eval("type") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Price">
<ItemTemplate>
<asp:Label id="price_lbl" Runat="Server"
Text='<%# Eval("price") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:Button ID="ViewGrandChild_Button"
runat="server" Text="+" CommandName="Edit"/>
</ItemTemplate>
<EditItemTemplate>
<asp:Button ID="CancelGrandChild_Button"
runat="server" Text="-" CommandName="Cancel" />
*GrandChildGridView will come here
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Grand Child GridViewThe <SelectCommand="select [lorange],[hirange],roysched.royalty
from [roysched], [titles] where
titles.title_id=roysched.title_id
and (roysched.title_id=?)">
<SelectParameters>
<asp:SessionParameter Name="title_id"
SessionField="TitleID" Type="String"/>
</SelectParameters>
There is no need to use <asp:GridView ID="GrandChildGridView" runat="server"
AllowPaging="true" PageSize="4"
DataSourceID="GrandChildSqlDataSource">
</asp:GridView>
Points of InterestIt is important to know that I have used the If any parent More importantly, it can be implemented for any number of levels by simply keeping the track of primary keys and edit indexes of all parent | ||||||||||||||||||||