如何在ASP.NET中最好地填充HTML表格?

时间:2022-10-30 14:35:24

This is what I've got. It works. But, is there a simpler or better way?

这就是我所拥有的。有用。但是,有更简单或更好的方法吗?

ASPX Page…

<asp:Repeater ID="RepeaterBooks" runat="server">
    <HeaderTemplate>
        <table class="report">
            <tr>
                <th>Published</th>
                <th>Title</th>
                <th>Author</th>
                <th>Price</th>
            </tr>
    </HeaderTemplate>
    <ItemTemplate>
            <tr>
                <td><asp:Literal ID="LiteralPublished" runat="server" /></td>
                <td><asp:Literal ID="LiteralTitle" runat="server" /></td>
                <td><asp:Literal ID="LiteralAuthor" runat="server" /></td>
                <td><asp:Literal ID="LiteralPrice" runat="server" /></td>
            </tr>
    </ItemTemplate>
    <FooterTemplate>
        </table>
    </FooterTemplate>
</asp:Repeater>

ASPX.VB Code Behind…

ASPX.VB代码背后......

Protected Sub Page_Load( ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim db As New BookstoreDataContext
    RepeaterBooks.DataSource = From b In db.Books _
                               Order By b.Published _
                               Select b
    RepeaterBooks.DataBind()
End Sub

Sub RepeaterBooks_ItemDataBound( ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles RepeaterBooks.ItemDataBound
    If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
        Dim b As Book = DirectCast(e.Item.DataItem, Book)
        DirectCast(e.Item.FindControl("LiteralPublished"), Literal).Text = "<nobr>" + b.Published.ToShortDateString + "</nobr>"
        DirectCast(e.Item.FindControl("LiteralTitle"), Literal).Text = "<nobr>" + TryNbsp(HttpContext.Current.Server.HtmlEncode(b.Title)) + "</nobr>"
        DirectCast(e.Item.FindControl("LiteralAuthor"), Literal).Text = "<nobr>" + TryNbsp(HttpContext.Current.Server.HtmlEncode(b.Author)) + "</nobr>"
        DirectCast(e.Item.FindControl("LiteralPrice"), Literal).Text = "<nobr>" + Format(b.Price, "c") + "</nobr>"
    End If
End Sub

Function TryNbsp(ByVal s As String) As String
    If s = "" Then
        Return "&nbsp;"
    Else
        Return s
    End If
End Function

8 个解决方案

#1


4  

@Geoff

That sort of Eval statement was actually added in 2.0, but if performance is important Eval should be avoided since it uses Reflection.

那种Eval语句实际上是在2.0中添加的,但是如果性能很重要,应避免使用Eval,因为它使用了Reflection。

The repeater is a pretty good way of doing it, although it might be faster to generate the table in code:

转发器是一种非常好的方法,尽管在代码中生成表可能更快:

ASPX Page:

<table class="report" id="bookTable" runat="server">
        <tr>
            <th>Published</th>
            <th>Title</th>
            <th>Author</th>
            <th>Price</th>
        </tr>
 </table>

Code Behind:

Protected Sub Page_Load( ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not Page.IsPostback Then
        BuildTable()
    End If
End Sub

Private Sub BuildTable()
    Dim db As New BookstoreDataContext
    Dim bookCollection = from b in db.Books _
                         Order By b.Published _
                         Select b
    Dim row As HtmlTableRow
    Dim cell As HtmlTableCell

    For Each book As Books In bookCollection
        row = New HtmlTableRow()
        cell = New HtmlTableCell With { .InnerText = b.Published.ToShortDateString }
        row.Controls.Add(cell)
        cell = New HtmlTableCell With { .InnerText = TryNbsp(HttpContext.Current.Server.HtmlEncode(b.Title)) }
        row.Controls.Add(cell)
        cell = New HtmlTableCell With { .InnerText = TryNbsp(HttpContext.Current.Server.HtmlEncode(b.Author))
        row.Controls.Add(cell)
        cell = New HtmlTableCell With { .InnerText = Format(b.Price, "c") }
        row.Controls.Add(cell)
        bookTable.Controls.Add(row)
    Next

I guess it depends on how important speed is to you. For simplicity's sake I think I would go with the Repeater.

我想这取决于你的速度有多重要。为简单起见,我想我会选择Repeater。

#2


3  

The ListView control introduced with framework 3.5 might be a little bit better solution. Your markup would look like this:

框架3.5引入的ListView控件可能是一个更好的解决方案。你的标记看起来像这样:

<asp:ListView runat="server" ID="ListView1" 
    DataSourceID="SqlDataSource1">
  <LayoutTemplate>
    <table runat="server" id="table1" runat="server" >
      <tr runat="server" id="itemPlaceholder" ></tr>
    </table>
  </LayoutTemplate>
  <ItemTemplate>
    <tr runat="server>
      <td runat="server">
        <asp:Label ID="NameLabel" runat="server" 
          Text='<%#Eval("Name") %>' />
      </td>
    </tr>
  </ItemTemplate>
</asp:ListView>

#3


2  

In .Net 3.0+ you can replace your ItemDataBound to the asp:Literal by doing something like this:

在.Net 3.0+中,您可以通过执行以下操作将ItemDataBound替换为asp:Literal:

<ItemTemplate>
            <tr>
                <td><%# Eval("published") %></td>
                ...

where "published" is the name of a field in the data you have bound to the repeater

其中“已发布”是您绑定到转发器的数据中字段的名称

Edit: @Alassek: I think the performance hit of reflection is often over-emphasized. Obviously you need to benchmark performance of your app, but the hit of the Eval is likely measured in milliseconds. Unless your app is serving many concurrent hits, this probably isn't an issue, and the simplicity of the code using Eval, along with it being a good separation of the presentation, make it a good solution.

编辑:@Alassek:我认为反思的表现经常被过分强调。显然,您需要对应用程序的性能进行基准测试,但Eval的命中率可能以毫秒为单位。除非你的应用程序提供多个并发命中,否则这可能不是问题,使用Eval的代码的简单性,以及它是一个很好的表示分离,使它成为一个很好的解决方案。

#4


1  

I agree with Geoff, the only time we use Literals is if we want to do something different with the data ... for example, we might want a DueDate field to say "Today" or "Yesterday" instead of the actual date.

我同意Geoff的看法,我们唯一一次使用Literals是因为我们想要对数据做一些不同的事情......例如,我们可能希望DueDate字段说“Today”或“Yesterday”而不是实际日期。

#5


1  

This is what the GridView is for.

这就是GridView的用途。

<asp:GridView runat="server" DataSourceID="SqlDataSource1">
   <Columns>
      <asp:BoundField HeaderText="Published" DataField="Published" />
      <asp:BoundField HeaderText="Author" DataField="Author" />
   </Columns>
</asp:GridView>

#6


1  

I would use a GridView (or DataGrid, if you are using an older version of ASP.NET).

我会使用GridView(或DataGrid,如果您使用的是旧版本的ASP.NET)。

<asp:GridView ID="gvBooks" runat="server" AutoGenerateColumns="False">
    <Columns>
        <asp:BoundField HeaderText="Published" DataField="Published" />
        <asp:BoundField HeaderText="Title" DataField="Title" />                     
        <asp:BoundField HeaderText="Author" DataField="Author" />
        <asp:BoundField HeaderText="Price" DataField="Price" />
    </Columns>
</asp:GridView>

With some code-behind:

有些代码隐藏:

Private Sub gvBooksRowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvBooks.RowDataBound
     Select Case e.Row.RowType
        Case DataControlRowType.DataRow

            ''' Your code here '''

     End Select
End Sub

You can bind it in a similar way. The RowDataBound event is what you need.

您可以以类似的方式绑定它。 RowDataBound事件就是您所需要的。

#7


1  

If you don't need ASP.NET handled edit cabilities I would stay away from the DataGrid and the GridView ... they provide unnecessary bloat.

如果你不需要ASP.NET处理编辑功能,我会远离DataGrid和GridView ......它们提供了不必要的膨胀。

#8


0  

ALassek wrote:

…generate the table in code…

...在代码中生成表格...

I like the look of that! It seems MUCH less likely to produce a run-time exception due to a typo or field name change.

我喜欢那个样子!由于拼写错误或字段名称更改,似乎不太可能产生运行时异常。

#1


4  

@Geoff

That sort of Eval statement was actually added in 2.0, but if performance is important Eval should be avoided since it uses Reflection.

那种Eval语句实际上是在2.0中添加的,但是如果性能很重要,应避免使用Eval,因为它使用了Reflection。

The repeater is a pretty good way of doing it, although it might be faster to generate the table in code:

转发器是一种非常好的方法,尽管在代码中生成表可能更快:

ASPX Page:

<table class="report" id="bookTable" runat="server">
        <tr>
            <th>Published</th>
            <th>Title</th>
            <th>Author</th>
            <th>Price</th>
        </tr>
 </table>

Code Behind:

Protected Sub Page_Load( ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not Page.IsPostback Then
        BuildTable()
    End If
End Sub

Private Sub BuildTable()
    Dim db As New BookstoreDataContext
    Dim bookCollection = from b in db.Books _
                         Order By b.Published _
                         Select b
    Dim row As HtmlTableRow
    Dim cell As HtmlTableCell

    For Each book As Books In bookCollection
        row = New HtmlTableRow()
        cell = New HtmlTableCell With { .InnerText = b.Published.ToShortDateString }
        row.Controls.Add(cell)
        cell = New HtmlTableCell With { .InnerText = TryNbsp(HttpContext.Current.Server.HtmlEncode(b.Title)) }
        row.Controls.Add(cell)
        cell = New HtmlTableCell With { .InnerText = TryNbsp(HttpContext.Current.Server.HtmlEncode(b.Author))
        row.Controls.Add(cell)
        cell = New HtmlTableCell With { .InnerText = Format(b.Price, "c") }
        row.Controls.Add(cell)
        bookTable.Controls.Add(row)
    Next

I guess it depends on how important speed is to you. For simplicity's sake I think I would go with the Repeater.

我想这取决于你的速度有多重要。为简单起见,我想我会选择Repeater。

#2


3  

The ListView control introduced with framework 3.5 might be a little bit better solution. Your markup would look like this:

框架3.5引入的ListView控件可能是一个更好的解决方案。你的标记看起来像这样:

<asp:ListView runat="server" ID="ListView1" 
    DataSourceID="SqlDataSource1">
  <LayoutTemplate>
    <table runat="server" id="table1" runat="server" >
      <tr runat="server" id="itemPlaceholder" ></tr>
    </table>
  </LayoutTemplate>
  <ItemTemplate>
    <tr runat="server>
      <td runat="server">
        <asp:Label ID="NameLabel" runat="server" 
          Text='<%#Eval("Name") %>' />
      </td>
    </tr>
  </ItemTemplate>
</asp:ListView>

#3


2  

In .Net 3.0+ you can replace your ItemDataBound to the asp:Literal by doing something like this:

在.Net 3.0+中,您可以通过执行以下操作将ItemDataBound替换为asp:Literal:

<ItemTemplate>
            <tr>
                <td><%# Eval("published") %></td>
                ...

where "published" is the name of a field in the data you have bound to the repeater

其中“已发布”是您绑定到转发器的数据中字段的名称

Edit: @Alassek: I think the performance hit of reflection is often over-emphasized. Obviously you need to benchmark performance of your app, but the hit of the Eval is likely measured in milliseconds. Unless your app is serving many concurrent hits, this probably isn't an issue, and the simplicity of the code using Eval, along with it being a good separation of the presentation, make it a good solution.

编辑:@Alassek:我认为反思的表现经常被过分强调。显然,您需要对应用程序的性能进行基准测试,但Eval的命中率可能以毫秒为单位。除非你的应用程序提供多个并发命中,否则这可能不是问题,使用Eval的代码的简单性,以及它是一个很好的表示分离,使它成为一个很好的解决方案。

#4


1  

I agree with Geoff, the only time we use Literals is if we want to do something different with the data ... for example, we might want a DueDate field to say "Today" or "Yesterday" instead of the actual date.

我同意Geoff的看法,我们唯一一次使用Literals是因为我们想要对数据做一些不同的事情......例如,我们可能希望DueDate字段说“Today”或“Yesterday”而不是实际日期。

#5


1  

This is what the GridView is for.

这就是GridView的用途。

<asp:GridView runat="server" DataSourceID="SqlDataSource1">
   <Columns>
      <asp:BoundField HeaderText="Published" DataField="Published" />
      <asp:BoundField HeaderText="Author" DataField="Author" />
   </Columns>
</asp:GridView>

#6


1  

I would use a GridView (or DataGrid, if you are using an older version of ASP.NET).

我会使用GridView(或DataGrid,如果您使用的是旧版本的ASP.NET)。

<asp:GridView ID="gvBooks" runat="server" AutoGenerateColumns="False">
    <Columns>
        <asp:BoundField HeaderText="Published" DataField="Published" />
        <asp:BoundField HeaderText="Title" DataField="Title" />                     
        <asp:BoundField HeaderText="Author" DataField="Author" />
        <asp:BoundField HeaderText="Price" DataField="Price" />
    </Columns>
</asp:GridView>

With some code-behind:

有些代码隐藏:

Private Sub gvBooksRowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvBooks.RowDataBound
     Select Case e.Row.RowType
        Case DataControlRowType.DataRow

            ''' Your code here '''

     End Select
End Sub

You can bind it in a similar way. The RowDataBound event is what you need.

您可以以类似的方式绑定它。 RowDataBound事件就是您所需要的。

#7


1  

If you don't need ASP.NET handled edit cabilities I would stay away from the DataGrid and the GridView ... they provide unnecessary bloat.

如果你不需要ASP.NET处理编辑功能,我会远离DataGrid和GridView ......它们提供了不必要的膨胀。

#8


0  

ALassek wrote:

…generate the table in code…

...在代码中生成表格...

I like the look of that! It seems MUCH less likely to produce a run-time exception due to a typo or field name change.

我喜欢那个样子!由于拼写错误或字段名称更改,似乎不太可能产生运行时异常。