Gruppierte Listen mit ASP.NET und LINQ

Windows 8 hat sehr nette Funktionen um Daten zu gruppieren. Bekannt ist vielleicht das Semantic Zoom Control aus WinRT. Um mehr gemeinsamen Visual Basic Code zu nutzen im folgenden der Ansatz wie man grouped Lists mit ASP.NET und seinen Webforms Controls realisiert.

Gruppiert bedeutet, Daten anhand eines Kriterium zusammenzufassen. Eine Master Detail Ansicht bezieht seine Verschachtelung aus der Relation in der Datenbank. Hier soll sich aber die Gruppierung aus einer flachen Tabelle ergeben. Aus UX Sicht sind Listen mit gruppierten Datumswerten übersichtlicher. Folgendes Beispiel ist einer Jquery Mobile Seite entnommen. Ein LI Element erhält lediglich das Attribut data-role="list-divider".

jQuery mobile applied to a ListView of dates

Wie erhält man solche gruppierten Daten. Dies ist mit LINQ relativ einfach. Es wird nach Jahr gruppiert. Das klappt recht einfach, erzeugt aber eine generische anonyme Liste.

   1:   Dim Query = From s In students
   2:          Group s By s.datum.Value.Year.ToString Into newGroup()
   3:          orderby newGroup.Key
   4:          Select newGroup

Es wird so aus einer flachen Liste eine verschachtelte Liste. Die Grundlagen lassen sich bei MSDN nachlesen.

Da im weiteren das neue ASP.NET Model Binding genutzt werden soll, wird eine streng typisierte Liste benötigt. Das geht nur über den Umweg einer zwischen Klasse, die einen Key und  eine Liste (wieder streng typisiert) enthält.

   1:  Public Class groupedComments
   2:      Public Property key As String
   3:      Public Property gruppe() As liste()
   4:  End Class

So wird nun per LINQ Statement eine Gruppe pro Jahr aggregiert und dieser die zughörigen Einträge als Array zugeordnet. Fertig ist eine verschachtelte streng typisierte Liste.

   1:   Dim gruppe As List(Of groupedComments) = (From p In tabelle
   2:                 Group p By Key = p.datum.Value.Year.ToString Into g = Group
   3:              Select New groupedComments With {.key = Key, .gruppe = g}).toList

Und nun per URL (FriendlyUrl) die Ergebnismenge gefiltert und die GET Methode für das ASP.NET Webform Modelbinding angelegt. (website/suchen/1212)

   1:    Public Function KommentareGrid_GetData(<FriendlyUrlSegments(1)>
search As Integer) As List(Of groupedComments)
   2:  ...
   3:     Return gruppe

Wer MVVM kennt, wird dies als Viewmodel bezeichnen. Bleibt nur noch der View also die Sicht auf die Liste. Alles mit ASP.NET Listview per Deklaration in der ASPX Datei. Es werden zwei Listview geschachtelt, wobei das inneren über DataSource an das Gruppen Array vom Type Liste passend zum Key gebunden wird.

   1:  <asp:ListView EnableViewState="False"
   2:                ItemType="groupedComments"
   3:                ID="KommentareGrid" runat="server" 
SelectMethod="KommentareGrid_GetData">
   4:       <ItemTemplate>    <li class="list-group-item-heading">
   5:            <div><h4 class="list-group-item-heading"><%#Item.key%>  </h4></div>
   6:   
   7:             <asp:ListView EnableViewState="False" DataSource="<%#Item.gruppe%>"
   8:                  ItemType="liste"
   9:                  ID="HistorieListe" runat="server">
  10:                  <ItemTemplate>
  11:                     <li class="list-group-item">
  12:                     <div class="news-time">
  13:                     <span><%#Item.datum.Value.Day%> </span>
  14:                     <%#MonthName(Item.datum.Value.Month, True)%>
  15:                     </div>
  16:                     <div>
  17:                     <h4 class="list-group-item-heading"><%#Item.Action%> 
  18:              <%#Item.Mitarbeiter%></h4>
  19:                    <p class="list-group-item-text"><%#Item.Comments%></p>
  20:                    </div>
  21:                    </li>
  22:                  </ItemTemplate>
  23:             </asp:ListView>
  24:       </ItemTemplate>
  25:  </asp:ListView>

Wer genau hinsieht kann Bootstrap CSS Element erkennend. Folglich sieht das Ergebnis bei unserer Anwendung so aus.

image

Kommentare sind geschlossen