Reputation: 329
I need to display the results of two separate queries as side-by-side columns in the same html table. Each of the two data sets comes from a stored procedure via an ASP.NET SqlDataSource, and they each return the same number of rows. I would like the output to look like this:
<table>
<tr>
<td>Row 1 from Stored Procedure 1</td>
<td>Row 1 from Stored Procedure 2</td>
</tr>
<tr>
<td>Row 2 from Stored Procedure 1</td>
<td>Row 2 from Stored Procedure 2</td>
</tr>
...
<tr>
<td>Row n from Stored Procedure 1</td>
<td>Row n from Stored Procedure 2</td>
</tr>
</table>
Is it possible to accomplish this within a single ASP Repeater control using the "alternate row" functionality? Is it possible to execute two ASP Repeaters side-by-side? Is there another control that can accomplish this?
Upvotes: 1
Views: 4215
Reputation: 6249
Since both DataTables have the same number of rows, you can set the first table as the datasource and access the values from the second table using e.Item.ItemIndex
.
So this would be your Repeater
markup:
<asp:Repeater ID="rptData" runat="server" OnItemDataBound="rptData_ItemDataBound">
<HeaderTemplate>
<table border="1" >
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><asp:Label ID="lblFirst" runat="server" /></td>
<td><asp:Label ID="lblSecond" runat="server" /></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
And you would handle the OnItemDataBound
like so:
protected void rptData_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
((Label)e.Item.FindControl("lblFirst")).Text = ((DataRowView)e.Item.DataItem)["Value"].ToString();
((Label)e.Item.FindControl("lblSecond")).Text = this.dtSecond.Rows[e.Item.ItemIndex]["Value"].ToString();
}
}
Here is the rest of the code-behind so you have a complete working sample:
//PAGE-LEVEL VARIABLES
DataTable dtFirst = new DataTable();
DataTable dtSecond = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
this.PopulateDatasources();
this.rptData.DataSource = this.dtFirst;
this.rptData.DataBind();
}
private void PopulateDatasources()
{
DataRow row = null;
dtFirst.Columns.Add(new DataColumn("Value"));
dtSecond.Columns.Add(new DataColumn("Value"));
row = dtFirst.NewRow();
row["Value"] = "First - 01";
dtFirst.Rows.Add(row);
row = dtFirst.NewRow();
row["Value"] = "First - 02";
dtFirst.Rows.Add(row);
row = dtSecond.NewRow();
row["Value"] = "Second - 01";
dtSecond.Rows.Add(row);
row = dtSecond.NewRow();
row["Value"] = "Second - 02";
dtSecond.Rows.Add(row);
}
Let me know if this works for you.
Upvotes: 1
Reputation: 71
Do you have any column where you can join them? If yes, what you could do is join the tables in on DataSet with DataRelation and the in page you can get the Childs or the parent using this relationship, following an example
code behind:
protected void Page_Load(object sender, EventArgs e)
{
DataSet ds1 = new DataSet();
DataSet ds2 = new DataSet();
DataTable dt1 = new DataTable("Table1");
DataTable dt2 = new DataTable("Table2");
DataSet ds = new DataSet("DataSet");
dt1.Columns.Add("Eno", typeof(Int32));
dt1.Columns.Add("Ename", typeof(String));
dt1.Columns.Add("Salary", typeof(Double));
dt1.Columns.Add("Deptno", typeof(Int32));
dt1.PrimaryKey = new DataColumn[] { dt1.Columns["Eno"] };
dt2.Columns.Add("Deptno", typeof(Int32));
dt2.Columns.Add("Dname", typeof(String));
dt2.PrimaryKey = new DataColumn[] { dt2.Columns["Deptno"] };
ds1.Tables.Add(dt1);
ds2.Tables.Add(dt2);
// Loading data into dt1, dt2:
object[] o1 = { 1, "dvs.kiran kumar", 50000.50, 10 };
object[] o2 = { 2, "Raj", 4000.50, 20 };
object[] o3 = { 3, "Gary", 10000.50, 30 };
object[] c1 = { 10, "MFG" };
object[] c2 = { 20, "EAS" };
object[] c3 = { 30, "E&U" };
object[] c4 = { 40, "PES" };
dt2.Rows.Add(c1);
dt2.Rows.Add(c2);
dt2.Rows.Add(c3);
dt2.Rows.Add(c4);
dt1.Rows.Add(o1);
dt1.Rows.Add(o2);
dt1.Rows.Add(o3);
DataSet dsJoined = new DataSet();
dsJoined.Tables.Add(ds1.Tables[0].Copy());
dsJoined.Tables.Add(ds2.Tables[0].Copy());
DataRelation drel = new DataRelation("EquiJoin", dsJoined.Tables[1].Columns["Deptno"], dsJoined.Tables[0].Columns["Deptno"]);
dsJoined.Relations.Add(drel);
rptJoined.DataSource = dsJoined.Tables[1];
rptJoined.DataBind();
}
markup:
<asp:Repeater runat="server" ID="rptJoined">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
Depto: <%# ((System.Data.DataRowView) Container.DataItem)["Dname"] %>
</td>
<asp:Repeater runat="server" ID="rptChild" DataSource='<%# ((System.Data.DataRowView) Container.DataItem).Row.GetChildRows("EquiJoin") %>'>
<ItemTemplate>
<td>
Ename: <%# ((System.Data.DataRow) Container.DataItem)["Ename"] %>
</td>
</ItemTemplate>
</asp:Repeater>
<tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Another option is use the OnItemDataBound event from the repeater and get the values in the code behind.
Code behind:
protected void rptJoined_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
DataRowView drv = (DataRowView)e.Item.DataItem;
Literal ltrColumn1 = (Literal)e.Item.FindControl("ltrColumn1");
Literal ltrColumn2 = (Literal)e.Item.FindControl("ltrColumn2");
ltrColumn1.Text = drv["Dname"].ToString();
var childs = drv.Row.GetChildRows("EquiJoin");
if (childs.Count() > 0)
{
ltrColumn2.Text = childs[0]["Ename"].ToString();
}
}
}
markup:
<asp:Repeater runat="server" ID="rptJoined" OnItemDataBound="rptJoined_ItemDataBound">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Literal runat="server" ID="ltrColumn1" />
</td>
<td>
<asp:Literal runat="server" ID="ltrColumn2" />
</td>
<tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Cheers
Upvotes: 0
Reputation: 27012
I don't think it's possible with a table.
You could do something like this:
<div style="width:500px;float:left;">
<asp:Repeater ID="Repeater1">
<div style="width:100%;height:25px;"><asp:Label ID="RowDataLabel"></asp:Label></div>
</asp:Repeater>
</div>
<div style="width:500px;float:left;">
<asp:Repeater ID="Repeater2">
<div style="width:100%;height:25px;"><asp:Label ID="RowDataLabel"></asp:Label></div>
</asp:Repeater>
</div>
(I know I'm missing some markup)
How this actually renders would depend on how much and how similar the data in each row is.. one really long bit of data could throw off the whole layout. You could also use <ul>
's instead of <div>
's if you have trouble with the css.
Another option would be to get the two datasets in code, use LINQ to combine them, then render the single combined dataset to a grid or repeater.
Upvotes: 1