以下のようなasp.netリピーターを使用してテーブル構造を構築しようとしています:
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を追加することに行き詰まりました。リピーター内の単一のセルにテーブルを追加する方法がわかりません。データはDataTableからバインドする必要があります。
そして、以下はリピーターの私のコードです:
<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
誰かが私に非常に感謝するこの1つのアイデアを提案できますか?
さまざまなasp.netデータ表現コントロール(例:asp:Repeater
、asp:DataList
、asp:GridView
、asp:Table
など)をRepeaterコントロール内にネストできます。複数の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;
}
リピーターの2番目の項目に2つのテーブルをわざわざ追加するのはなぜですか? Repeater == Tableである必要はありません
代わりに、リピーターの<headertemplate>
に、マスターテーブルの最初の行と、必要な2つのテーブルすべてを含む2番目の行を配置します。次に、リピーターの<ItemTemplate>
を残りの行(3行目から下)に保持します。
コードビハインドを介して2つのテーブルにアクセスするか、プロパティまたは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行目にテーブルを本当に配置したい場合は、次のようにすることができます。
2つのPlaceHolder
をItemTemplate
に追加します。 1つはテーブルのある2番目の行用で、もう1つは他の行用です。可視性の基準をItemIndex
に設定します。 GridViewは、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を再びこれらの2つのテキストボックスにし、次に行4をテーブルなどにする場合は、PlaceHolderのvisibleプロパティでContainer.ItemIndex % 2 == 0
とContainer.ItemIndex % 2 == 1
を使用します。これは、上記のデモではリピーターの2行のみを想定しているためです。 。
次に、OnItemDataBound
イベントをリピーターに追加します。
<asp:Repeater ID="Repeaterp" runat="server" OnItemDataBound="Repeaterp_ItemDataBound">
次に、コードビハインドで、バインドされているアイテムが2行目であるかどうかを確認し、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();
}
}
私は最近忙しいので、コーディングの代わりに行う方法のロジックを紹介します。
1)ItemDataBoundイベントを親リピーターに追加します(id = "parentrepeater"と想定します)。
2)aspxファイルのリピーターitemtemplateに子リピーターを追加します(id = "childrepeater"と想定します)。
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();
}
}
この方法を使用すると、無制限のマルチレベルのネストされたリピーターを実現できます。