| | |
ASP.NET 2.0, Parent/Child Data Control?
Please support our ASP.NET advertiser: $4.95 a Month - ASP.NET Web Hosting – Click Here!
![]() |
•
•
Join Date: Dec 2004
Posts: 1,655
Reputation:
Solved Threads: 35
Has ASP.NET 2.0 introduced a simplified data control for displaying parent/child data?
Imagine a HelpDesk application, where you want to display all the "open tickets". I can see how you'd use a GridView for that.
However, each row in the resulting table should have the ability to, when clicked/selected show all the "details" for that ticket.
Make sense? Two separate queries, related by an identity field. I know how to do this with a DataGrid, and this is typically referred to as "Master/Detail" or "Parent/Child" data.
I'm just wondering if there is anything new in ASP.NET 2.0 that simplifies this.
Imagine a HelpDesk application, where you want to display all the "open tickets". I can see how you'd use a GridView for that.
However, each row in the resulting table should have the ability to, when clicked/selected show all the "details" for that ticket.
Make sense? Two separate queries, related by an identity field. I know how to do this with a DataGrid, and this is typically referred to as "Master/Detail" or "Parent/Child" data.
I'm just wondering if there is anything new in ASP.NET 2.0 that simplifies this.
•
•
Join Date: Dec 2004
Posts: 1,655
Reputation:
Solved Threads: 35
Experiments continue...
It's simple enough to create a SqlDataSource which selects all of the "master" records, and to bind that to a GridView. If one sets the "Enable Selection" to True, it adds a select command control to each row.
Then, add a second SqlDataSource, tied to a query or stored procedure that displays the detail. In the wizard, one can specify that a parameter comes from a control, in this case, our first GridView.
Create a second GridView, bound to the second SqlDataSource.
Now, when the user clicks "Select" in the parent GridView, the child GridView displays all the associated detail records.
All well and good. The issue is formatting. I don't want two separate GridViews. I want the second, child or "detail" GridView to display underneath the parent row. Each "detail" listing should be collapsible... it should be possible to display as many "detail" sections as the user wants.
Any suggestions on how to go about that?
It's simple enough to create a SqlDataSource which selects all of the "master" records, and to bind that to a GridView. If one sets the "Enable Selection" to True, it adds a select command control to each row.
Then, add a second SqlDataSource, tied to a query or stored procedure that displays the detail. In the wizard, one can specify that a parameter comes from a control, in this case, our first GridView.
Create a second GridView, bound to the second SqlDataSource.
Now, when the user clicks "Select" in the parent GridView, the child GridView displays all the associated detail records.
All well and good. The issue is formatting. I don't want two separate GridViews. I want the second, child or "detail" GridView to display underneath the parent row. Each "detail" listing should be collapsible... it should be possible to display as many "detail" sections as the user wants.
Any suggestions on how to go about that?
•
•
Join Date: Dec 2004
Posts: 1,655
Reputation:
Solved Threads: 35
So many of the C#/ASP.NET threads I start end up with me just talking to myself. Hopefully, everyone is following along diligently, just waiting for a chance to jump in. THIS IS YOUR CHANCE!
I've given up on GridView. I'm using Repeaters, instead. I have one "static" Repeater, coded to display the "Parent" rows. There is a LinkButton element in the Repeater. There is also a PlaceHolder.
When the LinkButton is clicked, I dynamically create a second Repeater, completely in code, bind it in code, and add that Repeater to the PlaceHolder. This dynamic Repeater contains all the "Detail" rows.
The issue I need some help with is, re-creating all of the dynamic Repeaters which the user has chosen to display. I fully understand the issue... the codepath only creates one dynamic Repeater on PostBack. I need some mechanism to re-create all previously rendered Repeaters. Session?
Note: this renders very ugly for now. First comes logic, then comes StyleSheets
Here is the declarative syntax for the page.:
And the code-behind:
BTW, if you've ever wondered how to dynamically create a Repeater complete with an ItemTemplate and DataBinding, programmatically, the above code in orange demonstrates this very nicely! You're welcome.
Now, once I get this issue resolved, the next step is to implement the detail rows as ClientCallbacks, so that as new records are added to the details table, they'll "magically appear" in the page.
I've given up on GridView. I'm using Repeaters, instead. I have one "static" Repeater, coded to display the "Parent" rows. There is a LinkButton element in the Repeater. There is also a PlaceHolder.
When the LinkButton is clicked, I dynamically create a second Repeater, completely in code, bind it in code, and add that Repeater to the PlaceHolder. This dynamic Repeater contains all the "Detail" rows.
The issue I need some help with is, re-creating all of the dynamic Repeaters which the user has chosen to display. I fully understand the issue... the codepath only creates one dynamic Repeater on PostBack. I need some mechanism to re-create all previously rendered Repeaters. Session?
Note: this renders very ugly for now. First comes logic, then comes StyleSheets
Here is the declarative syntax for the page.:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="show_tsr.aspx.cs" Inherits="show_tsr" %> <!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>Untitled Page</title> <link href="StyleSheet.css" rel="stylesheet" type="text/css" /> </head> <body> <form id="form1" runat="server"> <div> <table> <thead> <tr> <th>TSR #</th><th>Subject</th><th>Department</th><th>Application</th> </tr> </thead> <asp:Repeater ID="rptrIssue" runat="server" OnItemCommand="rptrIssue_ItemCommand"> <ItemTemplate> <tr> <td><%# DataBinder.Eval(Container, "DataItem.issue_id") %></td> <td><%# DataBinder.Eval(Container, "DataItem.subject") %></td> <td><%# DataBinder.Eval(Container, "DataItem.Dept") %></td> <td><%# DataBinder.Eval(Container, "DataItem.App") %></td> </tr> <tr> <td colspan="4"> <span> <asp:LinkButton ID="lnkbDetail" runat="server" CommandArgument='<%# DataBinder.Eval(Container, "DataItem.issue_id") %>'>+</asp:LinkButton> </span> <span> Problem Detail: </span> <span></span><%# DataBinder.Eval(Container, "DataItem.description") %></span> </td> </tr> <asp:PlaceHolder ID="phDetail" runat="server"></asp:PlaceHolder> </ItemTemplate> </asp:Repeater> </table> </div> </form> </body> </html>
And the code-behind:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class show_tsr : System.Web.UI.Page
{
public SqlConnection conn;
public SqlCommand cmd;
public SqlDataReader dr;
protected void Page_Load(object sender, EventArgs e)
{
Session.Add("auth_pers", 1);
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["HELPDESKConnectionString"].ConnectionString);
conn.Open();
cmd = new SqlCommand("spSelectIssueByPers", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@pers", SqlDbType.Int);
cmd.Parameters["@pers"].Value = Session["auth_pers"];
dr = cmd.ExecuteReader();
rptrIssue.DataSource = dr;
rptrIssue.DataBind();
dr.Close();
}
protected void rptrIssue_ItemCommand(Object Sender, RepeaterCommandEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
cmd.Parameters.Clear();
cmd = new SqlCommand("spSelectHistoryByIssue", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("issue_id", SqlDbType.Int);
cmd.Parameters["issue_id"].Value = System.Convert.ToInt32(e.CommandArgument);
RowTemplate myRow = new RowTemplate();
Repeater rptrDetails = new Repeater();
dr = cmd.ExecuteReader();
rptrDetails.DataSource = dr;
rptrDetails.ItemTemplate = myRow;
rptrDetails.DataBind();
dr.Close();
PlaceHolder ph = (PlaceHolder)e.Item.FindControl("phDetail");
ph.Controls.Add(rptrDetails);
}
}
public class RowTemplate : ITemplate
{
public void InstantiateIn(Control container)
{
LiteralControl detailRow = new LiteralControl();
detailRow.DataBinding += new EventHandler(detailRow_DataBinding);
container.Controls.Add(detailRow);
}
public void detailRow_DataBinding(object sender, EventArgs e)
{
LiteralControl detailRow = (LiteralControl)sender;
RepeaterItem container = (RepeaterItem)detailRow.NamingContainer;
detailRow.Text = "<tr><td>" + DataBinder.Eval(container, "DataItem.action") + "</td>" +
"<td>" + DataBinder.Eval(container, "DataItem.timestamp") + "</td>" +
"<td>" + DataBinder.Eval(container, "DataItem.name") + "</td>" +
"<td>" + DataBinder.Eval(container, "DataItem.detail") + "</td></tr>";
}
}
}BTW, if you've ever wondered how to dynamically create a Repeater complete with an ItemTemplate and DataBinding, programmatically, the above code in orange demonstrates this very nicely! You're welcome.
Now, once I get this issue resolved, the next step is to implement the detail rows as ClientCallbacks, so that as new records are added to the details table, they'll "magically appear" in the page.
•
•
Join Date: Dec 2004
Posts: 1,655
Reputation:
Solved Threads: 35
Figured it out. I'll write this up, eventually. The answer is to create a public class with two properties, the id of the record needed for the query to the details, and the UniqueID of the Placeholder for a pariticular row/item in the parent.
Store these objects in a List<> generic, marked as Serializable. Store the List object in ViewState.
Then, loop through the List, building the Repeater dynamically for each item in the List.
Store these objects in a List<> generic, marked as Serializable. Store the List object in ViewState.
Then, loop through the List, building the Repeater dynamically for each item in the List.
•
•
Join Date: Jan 2006
Posts: 275
Reputation:
Solved Threads: 11
Not had time to look over the code yet sorry. Couldnt you put a repeater in a user control and then you would be able to expand every one?
I cheat. I bought the Infragistics controls years ago as they save me so much time. They have had hierarachical grids for a few years in both win forms and asp.net.
I know its good to make your own, but why reinvent the wheel when there are other things that need doing
But if you do have the time then maybe worth thinking about writing the control from scratch based on the repeater rather than a user control?
I cheat. I bought the Infragistics controls years ago as they save me so much time. They have had hierarachical grids for a few years in both win forms and asp.net.
I know its good to make your own, but why reinvent the wheel when there are other things that need doing

But if you do have the time then maybe worth thinking about writing the control from scratch based on the repeater rather than a user control?
•
•
Join Date: Apr 2006
Posts: 1
Reputation:
Solved Threads: 0
•
•
•
•
Originally Posted by Craig Pelkie
Would the System.Web.UI.WebControls.DetailsView provide the detail display capabilities that you're after? In .NET 1.1 I coded an HTML table with embedded text boxes, the DetailsView provides similar functionality with the benefit of being a single control.
http://www.asp.net/QuickStart/util/s...terDetails.src
![]() |
Similar Threads
- Updated : Simple ASP.Net Login Page (ASP.NET)
- textarea Control in ASP.NET (ASP.NET)
- ASP.NET: Context.Items.Add question (ASP.NET)
Other Threads in the ASP.NET Forum
- Previous Thread: Launching site
- Next Thread: send email
| Thread Tools | Search this Thread |
.net 2.0 3.5 activexcontrol advice ajax alltypeofvideos asp asp.net bc30451 beginner bottomasp.net browser businesslogiclayer c# c#gridviewcolumn cac checkbox class commonfunctions confirmationcodegeneration contenttype countryselector dataaccesslayer database datagrid datagridview datagridviewcheckbox deployment development dgv dropdownlist dropdownmenu dynamic dynamically edit embeddingactivexcontrol fileuploader fill findcontrol flash flv formatdecimal forms formview gridview gudi iframe iis javascript jquery listbox menu microsoft mouse mssql multistepregistration nameisnotdeclared news objects opera panelmasterpagebuttoncontrols problem redirect registration relationaldatabases reportemail rotatepage schoolproject security serializesmo.table sessionvariables silverlight smartcard smoobjects software sql sql-server sqlserver2005 ssl textbox tracking treeview unauthorized validatedate validation vb.net video videos virtualdirectory vista visualstudio web webapplications webarchitecture webdevelopemnt webdevelopment webprogramming webservice youareanotmemberofthedebuggerusers






