代码之家  ›  专栏  ›  技术社区  ›  Jronny

使用表优化转发器的ASP.NET C代码

  •  2
  • Jronny  · 技术社区  · 16 年前

    关于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 回复  |  直到 9 年前
        1
  •  3
  •   m3kh    16 年前

    在我看来,没有中继器窃听是不可能的。不管怎样,有一个相当不规则的方法可能有效。也可以使用两个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>
    -->
    
        2
  •  1
  •   Adam Ralph    16 年前

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

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

    而不是

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

    这意味着你不能写单曲 Category 后面跟着一个 Content . 你必须重复 类别 价值观,然后 内容 价值观,正如你已经做的。

    我认为你使用的方法没有任何问题。使用两个中继器而不是一个中继器的开销应该可以忽略不计。

    另一种方法是在每列中嵌套一个表。这将允许您只使用一个中继器,但最终得到的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>
    
        3
  •  1
  •   Jacob    16 年前

    如果将内容放在表中很重要,那么可以将表“旋转”成不同的结构并绑定到该结构上。或者,如果数据在一个表中并不重要,您可以将这些项放在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"))
    
        4
  •  0
  •   GxG    16 年前

    如果我误解了,请纠正我,但在我看来,您只能使用一个中继器,将第一个中继器集成到headerceplate标记中,将第二个中继器集成到itemtemplate中。

    推荐文章