Question

C'est ce que j'ai.Ça marche.Mais existe-t-il un moyen plus simple ou meilleur ?

Page ASPX…

<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>

Code ASPX.VB derrière…

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
Était-ce utile?

La solution

@Geoff

Ce type d'instruction Eval a en fait été ajouté dans la version 2.0, mais si les performances sont importantes, Eval doit être évité car il utilise Reflection.

Le répéteur est un très bon moyen de le faire, même s'il peut être plus rapide de générer la table en code :

Page ASPX :

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

Code derrière :

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

Je suppose que cela dépend de l'importance que vous accordez à la vitesse.Par souci de simplicité, je pense que j'opterais pour le Repeater.

Autres conseils

Le ListeView le contrôle introduit avec le framework 3.5 pourrait être une solution un peu meilleure.Votre balisage ressemblerait à ceci :

<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>

Dans .Net 3.0+, vous pouvez remplacer votre ItemDataBound par asp:Literal en faisant quelque chose comme ceci :

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

où "publié" est le nom d'un champ dans les données que vous avez liées au répéteur

Modifier:@Alassek:Je pense que l’impact de la réflexion sur la performance est souvent surestimé.Évidemment, vous devez évaluer les performances de votre application, mais le résultat de l'évaluation est probablement mesuré en millisecondes.À moins que votre application ne diffuse de nombreux accès simultanés, ce n'est probablement pas un problème, et la simplicité du code utilisant Eval, ainsi qu'une bonne séparation de la présentation, en font une bonne solution.

C'est à cela que sert GridView.

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

J'utiliserais un GridView (ou DataGrid, si vous utilisez une ancienne version d'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>

Avec du 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

Vous pouvez le lier de la même manière.L'événement RowDataBound est ce dont vous avez besoin.

Je suis d'accord avec Geoff, la seule fois où nous utilisons Literals c'est si nous voulons faire quelque chose différent avec les données.
Par exemple, nous pourrions vouloir un DueDate champ pour indiquer « Aujourd'hui » ou « Hier » au lieu de la date réelle.

ALassek a écrit:

…générer la table en code…

J'aime ce look !Il semble BEAUCOUP moins susceptible de produire une exception d'exécution en raison d'une faute de frappe ou d'un changement de nom de champ.

Si vous n'avez pas besoin des capacités d'édition gérées par ASP.NET, je le ferais reste loin à partir du DataGrid et du GridView...ils fournissent ballonnement inutile.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top