I am trying to build a table structure using asp.net Repeater like this below:
column 1 | Column 2
Row1 cell1 cell2
---------------------------------------
TABLE 1 TABLE 2
----------------------------------
col1|Col2|Col3_ same column and rows are here as well
Row2 row1____|____|____
row2___ |____|_____
row3____|____|_____
But I got stuck in adding Table 1 and Table 2 for the Row 2. I am not sure how to add the table in a single cell inside the Repeater and the data needs to binding from the DataTable.
And below is my code for Repeater:
<asp:Repeater ID="Repeaterp" runat="server">
<HeaderTemplate>
<table>
<tr><th>usedcount</th><th>notUsedCount</th></tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><asp:TextBox runat="server" ID="txtAvai" Text='<%#Eval("Count") %>' ReadOnly="true"></asp:TextBox></td>
<td><asp:TextBox runat="server" ID="txtConv" Text='' ReadOnly="true"></asp:TextBox></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater
Could any one please suggest any idea on this one that would be very grateful to me?
You can nest different asp.net Data Representation controls (e.g. asp:Repeater
, asp:DataList
, asp:GridView
or asp:Table
etc.) inside a Repeater control. I have added a quick example for making a nested structure with multiple Repeater controls:
<asp:Repeater ID="RepeaterTable" OnItemDataBound="RepeaterTable_ItemDataBound" runat="server">
<HeaderTemplate>
<table>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<asp:Panel ID="PanelTextBoxes" runat="server">
<tr>
<td>
<asp:TextBox ID="txtAvai" Text='<%# Eval("Count") %>' runat="server"></asp:TextBox>
</td>
<td>
<asp:TextBox ID="txtConv" Text='' runat="server"></asp:TextBox>
</td>
</tr>
</asp:Panel>
<asp:Panel ID="PanelTables" runat="server">
<tr>
<td>
<asp:Repeater ID="RepeaterTable1" OnItemDataBound="RepeaterTable1_ItemDataBound" runat="server">
<HeaderTemplate>
<table>
<tr>
<th>T1 Col 1</th>
<th>T1 Col 2</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="lblCol1" runat="server" Text='<%# Eval("Col1") %>'></asp:Label>
</td>
<td>
<asp:Label ID="lblCol2" runat="server" Text='<%# Eval("Col2") %>'></asp:Label>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</td>
<td>
<asp:Repeater ID="RepeaterTable2" OnItemDataBound="RepeaterTable2_ItemDataBound" runat="server">
<HeaderTemplate>
<table>
<tr>
<th>T2 Col 1</th>
<th>T2 Col 2</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="lblCol1" runat="server" Text='<%# Eval("Col1") %>'></asp:Label>
</td>
<td>
<asp:Label ID="lblCol2" runat="server" Text='<%# Eval("Col2") %>'></asp:Label>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</td>
</tr>
</asp:Panel>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
DataTable TempDT = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
getData();
}
}
// create DataTable 3 x 2
public void getData()
{
TempDT = new DataTable();
TempDT.Columns.Add("Col1");
TempDT.Columns.Add("Col2");
TempDT.Columns.Add("Count");
TempDT.Rows.Add("Temp", "Temp", 100);
TempDT.Rows.Add("Temp", "Temp", 100);
TempDT.Rows.Add("Temp", "Temp", 100);
// store DataTable into ViewState from lost on PostBack
ViewState["DT"] = TempDT;
RepeaterTable.DataSource = TempDT;
RepeaterTable.DataBind();
}
// Calls parent Repeater on Binding Data
protected void RepeaterTable_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// check Repeater item type is not in edit mode
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
DataTable dt = new DataTable();
// get and set DataTable from ViewState
dt = ViewState["DT"] as DataTable;
Repeater RepeaterTable1 = e.Item.FindControl("RepeaterTable1") as Repeater;
Repeater RepeaterTable2 = e.Item.FindControl("RepeaterTable2") as Repeater;
RepeaterTable1.DataSource = dt;
RepeaterTable1.DataBind(); // calls RepeaterTable1_ItemDataBound event
RepeaterTable2.DataSource = dt;
RepeaterTable2.DataBind(); // // calls RepeaterTable2_ItemDataBound event
Panel PanelTextBoxes = e.Item.FindControl("PanelTextBoxes") as Panel;
Panel PanelTables = e.Item.FindControl("PanelTables") as Panel;
// show only first structure
if (e.Item.ItemIndex != 0)
{
PanelTextBoxes.Visible = false;
PanelTables.Visible = false;
}
}
}
// Calls child Repeater on Binding Data
protected void RepeaterTable1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// check Repeater item type is not in edit mode
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
//.. here is code when child repeater is binding
}
}
// Calls child Repeater on Binding Data
protected void RepeaterTable2_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// check Repeater item type is not in edit mode
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
//.. here is code when child repeater is binding
}
}
If you don't want to repeat the whole structure then just add below code in RepeaterTable_ItemDataBound
event:
Panel PanelTextBoxes = e.Item.FindControl("PanelTextBoxes") as Panel;
Panel PanelTables = e.Item.FindControl("PanelTables") as Panel;
if (e.Item.ItemIndex != 0)
{
PanelTextBoxes.Visible = false;
PanelTables.Visible = false;
}
Why bother adding the two tables in the repeater's second item? It's not required that Repeater==Table
Instead, in the repeater's <headertemplate>
put the first row of the Master table, and the second row with all the 2 tables you want inside it. Then keep the repeater's <ItemTemplate>
for the rest of the rows (from 3rd row downwards)
You can access the two tables via your code behind or set values with properties or Eval
Here's how your .aspx may looklike:
(I added XmlDataSource1
for repeater just to make the binding works, I also used the property <%= this.ContentString %>
which I will declare and set in the code behind afterwards)
<asp:Repeater ID="Repeaterp" runat="server" DataSourceID="XmlDataSource1">
<HeaderTemplate>
<table>
<%--------Your Master Table--------%>
<tr>
<th>usedcount
</th>
<th>notUsedCount
</th>
</tr>
<tr>
<td>Row1 Cell1</td>
<td>Row1 Cell2</td>
</tr>
<tr>
<td>
<%----------------First Inner Table------------------%>
<asp:Table ID="Table1" runat="server">
<asp:TableHeaderRow>
<asp:TableHeaderCell>
Header
</asp:TableHeaderCell>
<asp:TableHeaderCell>
Header
</asp:TableHeaderCell>
</asp:TableHeaderRow>
<asp:TableRow>
<asp:TableCell>
<%---Add your conents as properties----%>
<%= this.ContentString %>
</asp:TableCell>
<asp:TableCell>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>
content
</asp:TableCell>
<asp:TableCell>
content
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>
content
</asp:TableCell>
<asp:TableCell>
content
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</td>
<td>
<%----------------Second Inner Table------------------%>
<asp:Table ID="Table2" runat="server">
<asp:TableHeaderRow>
<asp:TableHeaderCell>
Header
</asp:TableHeaderCell>
<asp:TableHeaderCell>
Header
</asp:TableHeaderCell>
</asp:TableHeaderRow>
<asp:TableRow>
<asp:TableCell>
<%---Add your conents as properties----%>
<%= this.ContentString %>
</asp:TableCell>
<asp:TableCell>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>
content
</asp:TableCell>
<asp:TableCell>
content
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>
content
</asp:TableCell>
<asp:TableCell>
content
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</td>
</tr>
<%-- Closing the second row of master table --%>
<%-- Everything is completed in the repeater's header! --%>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%--continue master table as usual--%> </td>
<td></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</Table>
</FooterTemplate>
</asp:Repeater>
Here's the code behind, notice the property ContentString
. and how to access the tables at row 2 after binding the repeater:
public partial class _Default : Page
{
private string strContent;
// notice the property that the tables can read as in the aspx code above
public String ContentString
{
get { return strContent; }
}
protected void Page_Load(object sender, EventArgs e)
{
strContent = "Your Content";
Repeaterp.DataBind();
// here's how to access the two tables
Table Table1 = (Table)Repeaterp.Controls[0].FindControl("Table1");
Table Table2 = (Table)Repeaterp.Controls[0].FindControl("Table2");
}
}
You can nest different asp.net Data Representation controls (e.g. asp:Repeater
, asp:DataList
, asp:GridView
or asp:Table
etc.) inside a Repeater control. I have added a quick example for making a nested structure with multiple Repeater controls:
<asp:Repeater ID="RepeaterTable" OnItemDataBound="RepeaterTable_ItemDataBound" runat="server">
<HeaderTemplate>
<table>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<asp:Panel ID="PanelTextBoxes" runat="server">
<tr>
<td>
<asp:TextBox ID="txtAvai" Text='<%# Eval("Count") %>' runat="server"></asp:TextBox>
</td>
<td>
<asp:TextBox ID="txtConv" Text='' runat="server"></asp:TextBox>
</td>
</tr>
</asp:Panel>
<asp:Panel ID="PanelTables" runat="server">
<tr>
<td>
<asp:Repeater ID="RepeaterTable1" OnItemDataBound="RepeaterTable1_ItemDataBound" runat="server">
<HeaderTemplate>
<table>
<tr>
<th>T1 Col 1</th>
<th>T1 Col 2</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="lblCol1" runat="server" Text='<%# Eval("Col1") %>'></asp:Label>
</td>
<td>
<asp:Label ID="lblCol2" runat="server" Text='<%# Eval("Col2") %>'></asp:Label>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</td>
<td>
<asp:Repeater ID="RepeaterTable2" OnItemDataBound="RepeaterTable2_ItemDataBound" runat="server">
<HeaderTemplate>
<table>
<tr>
<th>T2 Col 1</th>
<th>T2 Col 2</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="lblCol1" runat="server" Text='<%# Eval("Col1") %>'></asp:Label>
</td>
<td>
<asp:Label ID="lblCol2" runat="server" Text='<%# Eval("Col2") %>'></asp:Label>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</td>
</tr>
</asp:Panel>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
DataTable TempDT = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
getData();
}
}
// create DataTable 3 x 2
public void getData()
{
TempDT = new DataTable();
TempDT.Columns.Add("Col1");
TempDT.Columns.Add("Col2");
TempDT.Columns.Add("Count");
TempDT.Rows.Add("Temp", "Temp", 100);
TempDT.Rows.Add("Temp", "Temp", 100);
TempDT.Rows.Add("Temp", "Temp", 100);
// store DataTable into ViewState from lost on PostBack
ViewState["DT"] = TempDT;
RepeaterTable.DataSource = TempDT;
RepeaterTable.DataBind();
}
// Calls parent Repeater on Binding Data
protected void RepeaterTable_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// check Repeater item type is not in edit mode
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
DataTable dt = new DataTable();
// get and set DataTable from ViewState
dt = ViewState["DT"] as DataTable;
Repeater RepeaterTable1 = e.Item.FindControl("RepeaterTable1") as Repeater;
Repeater RepeaterTable2 = e.Item.FindControl("RepeaterTable2") as Repeater;
RepeaterTable1.DataSource = dt;
RepeaterTable1.DataBind(); // calls RepeaterTable1_ItemDataBound event
RepeaterTable2.DataSource = dt;
RepeaterTable2.DataBind(); // // calls RepeaterTable2_ItemDataBound event
Panel PanelTextBoxes = e.Item.FindControl("PanelTextBoxes") as Panel;
Panel PanelTables = e.Item.FindControl("PanelTables") as Panel;
// show only first structure
if (e.Item.ItemIndex != 0)
{
PanelTextBoxes.Visible = false;
PanelTables.Visible = false;
}
}
}
// Calls child Repeater on Binding Data
protected void RepeaterTable1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// check Repeater item type is not in edit mode
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
//.. here is code when child repeater is binding
}
}
// Calls child Repeater on Binding Data
protected void RepeaterTable2_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// check Repeater item type is not in edit mode
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
//.. here is code when child repeater is binding
}
}
If you don't want to repeat the whole structure then just add below code in RepeaterTable_ItemDataBound
event:
Panel PanelTextBoxes = e.Item.FindControl("PanelTextBoxes") as Panel;
Panel PanelTables = e.Item.FindControl("PanelTables") as Panel;
if (e.Item.ItemIndex != 0)
{
PanelTextBoxes.Visible = false;
PanelTables.Visible = false;
}
If you really want to have a table in the second row of the repeater, you could do the following.
Add two PlaceHolder
to the ItemTemplate
. One for the second row with the tables and one for the other rows. Set their visibility bases on the ItemIndex
. Note that GridViews were used since they become table elements in HTML.
<ItemTemplate>
<asp:PlaceHolder ID="PlaceHolder1" runat="server" Visible='<%# Container.ItemIndex != 1 %>'>
<tr>
<td>
<asp:TextBox runat="server" ID="txtAvai" Text='<%#Eval("Count") %>' ReadOnly="true">
</asp:TextBox>
</td>
<td>
<asp:TextBox runat="server" ID="txtConv" Text='' ReadOnly="true">
</asp:TextBox>
</td>
</tr>
</asp:PlaceHolder>
<asp:PlaceHolder ID="PlaceHolder2" runat="server" Visible='<%# Container.ItemIndex == 1 %>'>
<tr>
<td>
<asp:GridView ID="GridView1" runat="server"></asp:GridView>
</td>
<td>
<asp:GridView ID="GridView2" runat="server"></asp:GridView>
</td>
</tr>
</asp:PlaceHolder>
</ItemTemplate>
If you want row 3 to be those 2 textboxes again and then row 4 the tables etc, use Container.ItemIndex % 2 == 0
and Container.ItemIndex % 2 == 1
in the visible property of the PlaceHolder, because the above demo assumes just 2 rows in the Repeater.
Next, add the OnItemDataBound
event to the Repeater.
<asp:Repeater ID="Repeaterp" runat="server" OnItemDataBound="Repeaterp_ItemDataBound">
And then in code behind see if the item being bound is the second row, find the GridViews and bind data to them. I've create a dummy DataTable
for this demo, but you can bind any source to them in the Repeaterp_ItemDataBound
method
protected void Repeaterp_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
//check if it is the second row
if (e.Item.ItemIndex == 1)
{
//find the gridviews in the repeater item using findcontrol
GridView gv1 = e.Item.FindControl("GridView1") as GridView;
GridView gv2 = e.Item.FindControl("GridView2") as GridView;
//create a dummy datatable for this demo
DataTable table = new DataTable();
table.Columns.Add("Col1", typeof(int));
table.Columns.Add("Col2", typeof(string));
table.Columns.Add("Col3", typeof(string));
//add some rows to the table
table.Rows.Add(0, "Row 1", "AAA");
table.Rows.Add(1, "Row 2", "BBB");
table.Rows.Add(2, "Row 3", "CCC");
//bind the data to the gridviews in the second row
gv1.DataSource = table;
gv2.DataSource = table;
gv1.DataBind();
gv2.DataBind();
}
}
I will give you the logic how to do instead of coding as I'm busy these days.
1) add ItemDataBound event to your parent repeater (assume id="parentrepeater".
2) add child repeater in your repeater itemtemplate in aspx file (assume id="childrepeater".
3) in parent's repeater ItemDataBound, find your child repeater and bind datasource.
protected void parent_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// check Repeater item type is not in edit mode
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
Repeater childRepeater = e.Item.FindControl("childrepeater") as Repeater;
childRepeater.DataSource = "Get Your Datasource here";
childRepeater.DataBind();
}
}
Using this method, you can achieve unlimited multi-level nested repeater.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With