创建以下内容时遇到了一些挑战:
我需要根据xml内容在ASP.NET中生成一些包含2列和4行的固定大小的表。所以我的html容器是一个表的倍数,具有固定大小的2列乘4行。在每个表中,每列将包含xml中的[item],其中列中的顶部单元格是[category]标签,下面的3个单元格包含[make#]标签;每个[make#]一个,总共4行。所以表可以容纳2 [item];每列一个。
假设我的源来自XML文件:
<items>
<item>
<category>Cat 1</category>
<make1>101</make1>
<make2>102</make2>
<make3>103</make3>
</item>
<item>
<category>Cat 2</category>
<make1>201</make1>
<make2>202</make2>
<make3>203</make3>
</item>
<item>
<category>Cat 3</category>
<make1>301</make1>
<make2>302</make2>
<make3>303</make3>
</item>
<item>
<category>Cat 4</category>
<make1>401</make1>
<make2></make2>
<make3></make3>
</item>
<item>
<category>Cat 5</category>
<make1>501</make1>
<make2>502</make2>
<make3</make3>
</item>
</items>
和我想要的5个类别的输出,其中每个类别最多可以在html下面有3个项目:
<table>
<tr> <td>Cat 1</td> <td>Cat 2</td> </tr>
<tr> <td>101</td> <td>201</td> </tr>
<tr> <td>102</td> <td>202</td> </tr>
<tr> <td>103</td> <td>203</td> </tr>
</table>
<table>
<tr> <td>Cat 3</td> <td>Cat 4</td> </tr>
<tr> <td>301</td> <td>401</td> </tr>
<tr> <td>302</td> <td> </td> </tr>
<tr> <td>303</td> <td> </td> </tr>
</table>
<table>
<tr> <td>Cat 5</td> <td> </td> </tr>
<tr> <td>501</td> <td> </td> </tr>
<tr> <td>502</td> <td> </td> </tr>
<tr> <td> </td> <td> </td> </tr>
</table>
我将如何实现这一目标?
注意我需要桌子,因为我正在使用带有硬编码旋转木马的旋转木马......
答案 0 :(得分:1)
经过一番讨论后,我认为我们得出结论,转发器方法并不是最好的选择。这里的基本问题是如何并排输入两个实体。有一个为此构建的asp.net控件:DataList。
使用DataList,您可以设置要重复的最大项目数以及重复项目的方向(水平/垂直)。
因此,您需要将以下DataList代码添加到您的aspx页面:
<asp:DataList ID="DataList1" runat="server" DataSourceID="XmlDataSource1" RepeatColumns="2" RepeatDirection="Horizontal">
<HeaderTemplate>Items</HeaderTemplate>
<ItemTemplate>
<table border=1>
<tr>
<td>
<%# XPath("category")%>
</td>
</tr>
<tr>
<td>
<%# XPath("make1")%>
</td>
</tr>
<tr>
<td>
<%# XPath("make2")%>
</td>
</tr>
<tr>
<td>
<%# XPath("make3")%>
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
这里的关键是每个项目的数据都绑定在<ItemTemplate>
中。然后DataList本身负责根据标志RepeatColumns="2"
和RepeatDirection="Horizontal"
安排每个项目。
一些快速<asp:XmlDataSource>
魔法:
<asp:XmlDataSource ID="XmlDataSource1" runat="server"
XPath="//items/item">
</asp:XmlDataSource>
其中XPath="//items/item"
将XmlDataSource指向xml中每个实体的位置。这与DataList绑定到DataList,并在DataList上使用以下标记:DataSourceID="XmlDataSource1"
在代码隐藏文件中,我作弊并将XML作为字符串提供:
this.XmlDataSource1.Data = @"<items> <item> <category>Cat 1</category> <make1>101</make1> <make2>102</make2> <make3>103</make3> </item> <item> <category>Cat 2</category> <make1>201</make1> <make2>202</make2> <make3>203</make3> </item> <item> <category>Cat 3</category> <make1>301</make1> <make2>302</make2> <make3>303</make3> </item> <item> <category>Cat 4</category> <make1>401</make1> <make2></make2> <make3></make3> </item> <item> <category>Cat 5</category> <make1>501</make1> <make2>502</make2> <make3></make3> </item> </items>";
她工作了!
顺便说一句,我永远不会原谅你缺少的“&gt;”在原始帖子的XML中。开车送我坚果找到它。 :)现在,理所当然地认为最好的方法是将xml反序列化为.NET类并以正确的方式绑定所有内容(即:数据的代码隐藏绑定等),但总体思路是存在的。 / p>
关于嵌套表问题的OP评论:
GridList有一个名为RepeatLayout的属性。将此属性设置为RepeatLayout.Flow将使用其他元素而不是表。来自MSDN:
显示的项目没有表格结构。渲染标记由span元素组成,项目由br元素分隔。 Layouts for each enum here
此外,本文还讨论了DataGrid,DataList和Repeater MSDN之间的差异
OLD ANSWER:
我在考虑接受两个项目实体作为参数的Usercontrol。
因此,如果您有一个名为Item的类:
public class Item
{
public string Category{get;set;}
public List<string> Makes { get; set; }
}
你的UserControl看起来像这样: (C ++)
<table>
<tr>
<td><asp:Label ID="lblCategory1" runat="server" /></td>
<td><asp:Label ID="lblCategory2" runat="server" /></td>
</tr>
<asp:Repeater ID="rptMakes" runat="server">
<HeaderTemplate><tr></tr></HeaderTemplate>
<ItemTemplate>
<td>
<asp:Label ID="lblMake1" runat="server" />
</td>
<td>
<asp:Label ID="lblMake2" runat="server" />
</td>
</ItemTemplate>
<SeparatorTemplate></tr><tr></SeparatorTemplate>
<FooterTemplate>
</tr>
</FooterTemplate>
</asp:Repeater>
</table>
并在.cs页面上这样:
private Item Item2;
protected override void OnInit(EventArgs e)
{
this.rptMakes.ItemDataBound += new RepeaterItemEventHandler(rptMakes_ItemDataBound);
base.OnInit(e);
}
void rptMakes_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
((Label)e.Item.FindControl("lblMake1")).Text = e.Item.DataItem.ToString();
if (this.Item2 != null)
{
((Label)e.Item.FindControl("lblMake2")).Text = this.Item2.Makes[e.Item.ItemIndex];
}
else
{
((Label)e.Item.FindControl("lblMake2")).Text = " ";
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
public void Populate(Item item1, Item item2)
{
this.lblCategory1.Text = item1.Category;
if (item2 != null)
{
this.lblCategory2.Text = item2.Category;
}
else
{
this.lblCategory2.Text = " ";
}
this.Item2 = item2;
this.rptMakes.DataSource = item1.Makes;
this.rptMakes.DataBind();
}
从那里开始,只需迭代aspx页面上的原始Item实体列表,并将每两个实体传递给UC。