在C#中生成动态表内容

时间:2011-11-04 21:12:55

标签: arrays dynamic html-table repeater

创建以下内容时遇到了一些挑战:

我需要根据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>&nbsp;</td> </tr> 
<tr> <td>303</td> <td>&nbsp;</td> </tr> 
</table>
<table> 
<tr> <td>Cat 5</td> <td>&nbsp;</td> </tr> 
<tr> <td>501</td> <td>&nbsp;</td> </tr> 
<tr> <td>502</td> <td>&nbsp;</td> </tr> 
<tr> <td>&nbsp;</td> <td>&nbsp;</td> </tr> 
</table>

我将如何实现这一目标?

注意我需要桌子,因为我正在使用带有硬编码旋转木马的旋转木马......

1 个答案:

答案 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 = "&nbsp;";
        }
    }
}

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 = "&nbsp;";
    }
    this.Item2 = item2;
    this.rptMakes.DataSource = item1.Makes;
    this.rptMakes.DataBind();
}

从那里开始,只需迭代aspx页面上的原始Item实体列表,并将每两个实体传递给UC。