Wie fülle ich am besten eine HTML-Tabelle in ASP.NET?
Frage
Das ist es, was ich habe.Es klappt.Aber gibt es einen einfacheren oder besseren Weg?
ASPX-Seite…
<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 dahinter…
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 " "
Else
Return s
End If
End Function
Lösung
@Geoff
Diese Art von Eval-Anweisung wurde tatsächlich in 2.0 hinzugefügt, aber wenn die Leistung wichtig ist, sollte Eval vermieden werden, da es Reflection verwendet.
Der Repeater ist eine ziemlich gute Möglichkeit, dies zu tun, obwohl es möglicherweise schneller ist, die Tabelle im Code zu generieren:
ASPX-Seite:
<table class="report" id="bookTable" runat="server">
<tr>
<th>Published</th>
<th>Title</th>
<th>Author</th>
<th>Price</th>
</tr>
</table>
Code dahinter:
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
Ich denke, es hängt davon ab, wie wichtig Geschwindigkeit für Sie ist.Der Einfachheit halber würde ich mich für den Repeater entscheiden.
Andere Tipps
Der Listenansicht Die mit Framework 3.5 eingeführte Steuerung könnte eine etwas bessere Lösung sein.Ihr Markup würde so aussehen:
<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>
In .Net 3.0+ können Sie Ihren ItemDataBound durch asp:Literal ersetzen, indem Sie Folgendes tun:
<ItemTemplate>
<tr>
<td><%# Eval("published") %></td>
...
Dabei ist „veröffentlicht“ der Name eines Felds in den Daten, die Sie an den Repeater gebunden haben
Bearbeiten:@Alassek:Ich denke, dass der Leistungserfolg der Reflexion oft überbetont wird.Natürlich müssen Sie die Leistung Ihrer App messen, aber der Erfolg der Evaluierung wird wahrscheinlich in Millisekunden gemessen.Sofern Ihre App nicht viele gleichzeitige Zugriffe bereitstellt, stellt dies wahrscheinlich kein Problem dar, und die Einfachheit des Codes mit Eval sowie die gute Trennung der Präsentation machen es zu einer guten Lösung.
Dafür ist GridView gedacht.
<asp:GridView runat="server" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField HeaderText="Published" DataField="Published" />
<asp:BoundField HeaderText="Author" DataField="Author" />
</Columns>
</asp:GridView>
Ich würde ein GridView verwenden (oder DataGrid, wenn Sie eine ältere Version von ASP.NET verwenden).
<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>
Mit etwas CodeBehind:
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
Sie können es auf ähnliche Weise binden.Das RowDataBound-Ereignis ist genau das, was Sie brauchen.
Ich stimme Geoff zu, das einzige Mal, das wir verwenden Literals
ist, wenn wir etwas tun wollen anders mit den Daten.
Zum Beispiel möchten wir vielleicht eine DueDate
Geben Sie in das Feld „Heute“ oder „Gestern“ anstelle des tatsächlichen Datums ein.
ALassek schrieb:
…die Tabelle im Code generieren…
Mir gefällt das Aussehen!Es ist VIEL unwahrscheinlicher, dass es aufgrund eines Tippfehlers oder einer Änderung des Feldnamens zu einer Laufzeitausnahme kommt.
Wenn Sie keine von ASP.NET verwalteten Bearbeitungsfunktionen benötigen, würde ich das tun Bleib weg aus dem DataGrid und dem GridView ...Sie liefern unnötiges Aufblähen.