我正在尝试使用asp.net Repeater构建一个表结构,如下所示:
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____|____|_____
但是我坚持为第2行添加表1 和表2 。我不确定如何在Repeater内的单个单元格中添加表格,数据需要从DataTable绑定。
以下是我的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
任何人都可以就这个非常感激我的想法提出任何建议吗?
答案 0 :(得分:13)
您可以在Repeater控件中嵌套不同的asp.net数据表示控件(例如asp:Repeater
,asp:DataList
,asp:GridView
或asp:Table
等)。我添加了一个快速示例,用于创建具有多个Repeater控件的嵌套结构:
<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
}
}
如果您不想重复整个结构,请在RepeaterTable_ItemDataBound
事件中添加以下代码:
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;
}
答案 1 :(得分:6)
为什么要在转发器的第二项中添加两个表呢? 它不需要Repeater == Table
相反,在转发器<headertemplate>
中放置主表的第一行,第二行包含您想要的所有2个表。然后保留转发器<ItemTemplate>
用于其余行(从第3行向下)
您可以通过后面的代码访问这两个表,或者使用属性或Eval
设置值以下是.aspx的外观:
(我为转发器添加XmlDataSource1
只是为了使绑定工作,我还使用了属性<%= this.ContentString %>
,我将在之后的代码中声明并设置)
<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>
这里是后面的代码,请注意属性ContentString
。以及如何在绑定转发器后访问第2行的表:
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");
}
}
答案 2 :(得分:4)
如果你真的想在转发器的第二行有一个表,你可以这样做。
向PlaceHolder
添加两个ItemTemplate
。一个用于表格的第二行,另一个用于其他行。在ItemIndex
上设置其可见性基础。请注意,使用GridViews因为它们成为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>
如果您希望第3行再次成为这两个文本框,然后第4行表格等,请在PlaceHolder的visible属性中使用Container.ItemIndex % 2 == 0
和Container.ItemIndex % 2 == 1
,因为上面的演示只假设2行在中继器。
接下来,将OnItemDataBound
事件添加到Repeater。
<asp:Repeater ID="Repeaterp" runat="server" OnItemDataBound="Repeaterp_ItemDataBound">
然后在代码后面查看绑定的项是否是第二行,找到GridView并将数据绑定到它们。我为此演示创建了一个虚拟DataTable
,但您可以在Repeaterp_ItemDataBound
方法中将任何来源绑定到它们
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();
}
}
答案 3 :(得分:4)
我会告诉你如何做的逻辑而不是编码,因为我这些天很忙。
1)将ItemDataBound事件添加到您的父转发器(假设id =&#34; parentrepeater&#34;。
2)在aspx文件中的转发器itemtemplate中添加子转发器(假设id =&#34; childrepeater&#34;。
3)在父母的转发器ItemDataBound中,找到你的子转发器并绑定数据源。
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();
}
}
使用此方法,您可以实现无限制的多级嵌套转发器。