使用表优化用于中继器的asp.net C#代码

时间:2010-01-06 08:29:20

标签: c# asp.net repeater

在aspx上:

<table>
<tr>
<asp:Repeater ID="rptHeader" runat="server">
    <ItemTemplate>
        <th><%#Eval("Category")%></th>
    </ItemTemplate>
</asp:Repeater>
</tr>
<tr>
<asp:Repeater ID="rptContents" runat="server">
    <ItemTemplate>
        <td valign="top">
            <%#Eval("Content")%>
        </td>
    </ItemTemplate>
</asp:Repeater>
</tr>
</table>

关于代码隐藏:

protected void Page_Load(object sender, EventArgs e) 
{
    rptHeader.DataSource = DataSource;
    rptHeader.DataBind();
    rptContentBlocks.DataSource = DataSource;
    rptContentBlocks.DataBind();
}

这里的问题是,我们可以只使用一个中继器,而不是使用两个中继器吗? 我们实际上需要使用不同的表格行将标题与内容分开...

编辑:将rptHeader的ItemTemplate的html元素从<td>更改为<th>更清晰一些。 : - )

4 个答案:

答案 0 :(得分:3)

IMO如果没有转发器黑客攻击是不可能的。无论如何,有一种相当不规则的方法可能有效。您也可以使用两个foreach语句而不是中继器。

<强>代码

protected string[] headers = { "A", "B", "C", "D" };
protected string[] contents = { "Alpha", "Beta", "Counter", "Door" };

//string[] headers = { "A", "B", "C", "D" };
//string[] contents = { "Alpha", "Beta", "Counter", "Door" };

//DataList1.RepeatColumns = headers.Length;
//DataList1.DataSource = headers.Concat(contents);
//DataList1.DataBind();

Html标记

<table>
    <tr>
        <%foreach (string item in headers)
          { %>
          <th><%= item %></th>
        <% } %>
    </tr>
    <tr>
        <%foreach (string item in contents)
          { %>
          <td><%= item %></td>
        <% } %>
    </tr>
</table>
<!--
    <asp:DataList ID="DataList1" runat="server" RepeatDirection="Horizontal">
        <ItemTemplate>
            <%# Container.DataItem %>
        </ItemTemplate>
    </asp:DataList>
-->

答案 1 :(得分:1)

HTML表始终声明为嵌套在行中的单元格,即

<table>
    <tr>
        <td>
        ...
        </td>
    </tr>
</table>

而不是

<table>
    <td>
        <tr>
        ...
        </tr>
    </td>
</table>

这意味着您将无法编写单个Category后跟单个Content。您必须重复Category值,然后重复Content值。

我发现你使用的方法没有错。使用2个中继器而不是1个中继器应该是可以忽略不计的开销。

另一种方法是在每列中嵌套一个表。这将允许您只使用一个转发器,但生成的HTML将是相当人为和臃肿。我不推荐这种方法,但不知怎的,我不能阻止自己提供一个例子。

<table>
<tr>    
<asp:Repeater ID="rptHeader" runat="server">    
    <ItemTemplate>    
        <td>
            <table>
                <tr>
                    <td valign="top">    
                        <strong><%#Eval("Category")%></strong>    
                    </td>
                </tr>
                <tr>
                    <td valign="top">    
                        <%#Eval("Content")%>    
                    </td>
                </tr>
            </table>
        </td>
    </ItemTemplate>    
</asp:Repeater>    
</tr>    
</table>

答案 2 :(得分:1)

如果将内容放在表格中很重要,那么您可以将表格“旋转”为不同的结构并绑定在该结构上。或者,如果数据在表格中并不重要,您可以将项目放在div中并浮动它们,使它们并排放置。

修改

这就是旋转数据的意思。如果您的数据当前位于List<MyDataClass>之类的结构中,MyDataClass的定义如下:

class MyDataClass
{
    public string Category { get; set; }
    public string Content { get; set; }
    public int OtherField { get; set; }
}

...然后迭代结构时的逻辑布局如下所示:

MyDataClass[0]: Category, Content, OtherField
MyDataClass[1]: Category, Content, OtherField
...

旋转数据时,您可以将这些行转换为行和列。例如,您可以使用以下代码填充List<List<string>>

var rotated = new List<List<string>> {
    new List<string>(), new List<string>(), new List<string>(),
};
for each (MyDataClass object in myCollection) 
{
    rotated[0].Add(object.Category);
    rotated[1].Add(object.Content);
    rotated[2].Add(object.OtherField.ToString("n0"));
}

现在您的数据结构如下所示:

rotated[0]: MyDataClass[0].Category, MyDataClass[1].Category, ...
rotated[1]: MyDataClass[0].Content, MyDataClass[1].Content, ...
rotated[2]: MyDataClass[0].OtherField, MyDataClass[1].OtherField, ...

基本上,您将数据转换为可以直接放入表格的表单。

编辑2:

我实际上必须经常对报告进行这些类型的旋转,以便我为IEnumerable做了一个扩展方法,它将以更优雅的方式进行旋转。这是扩展方法:

public static class MyCollectionExtensionMethods
{
    public static IEnumerable<IEnumerable<TResult>> Rotate<TOrig, TResult>(
        this IEnumerable<TOrig> collection, 
        params Func<TOrig, TResult>[] valueSelectors)
    {
        return valueSelectors.Select(s => collection.Select(i => s(i)));
    }
}

以下是我如何使用它:

IEnumerable<IEnumerable<string>> rotated = data.Rotate(
    i => i.Category, i => i.Content, i => i.OtherField.ToString("n0"))

答案 3 :(得分:0)

如果我误解了,请纠正我,但听起来我只能使用一个中继器,将第一个中继器集成到HeaderTeplate标签中,第二个中继器集成到ItemTemplate中。