So wird’s gemacht: Gruppieren von Elementen in einer ListView (HTML)

[ Dieser Artikel richtet sich an Windows 8.x- und Windows Phone 8.x-Entwickler, die Windows-Runtime-Apps schreiben. Wenn Sie für Windows 10 entwickeln, finden Sie weitere Informationen unter neueste Dokumentation ]

Hier erfahren Sie, wie Sie Elemente in einer ListView gruppieren. Um Gruppeninformationen wie Gruppenköpfe und Gruppengrenzen anzuzeigen, müssen Sie für Ihre ListView ein Rasterlayout verwenden. Damit die Gruppierung überhaupt funktioniert, muss die loadingBehavior-Eigenschaft des ListView-Steuerelements auf "randomaccess" festgelegt werden (dies ist der Standardwert).

Wissenswertes

Technologien

Voraussetzungen

Anweisungen

Schritt 1: Erstellen Ihrer Daten

Für die Gruppierung sind zwei Datenquellen erforderlich: eine IListDataSource, die die Elemente enthält, und eine IListDataSource, die die Gruppen enthält. In der IListDataSource mit den Elementen enthält jedes Element eine groupKey-Eigenschaft, durch die es mit der Gruppe verknüpft wird, der es in der IListDataSource mit den Gruppen angehört.

  1. Fügen Sie Ihrem Projekt eine neue JavaScript-Datei hinzu, die Ihre Daten enthält. Benennen Sie sie mit "data.js".

  2. Erstellen Sie in der eben erstellten Datei data.js die zugrunde liegende Datenquelle, die Ihr ListView-Steuerelement mit Daten versorgt.

    Eine Möglichkeit zum Erstellen einer IListDataSource besteht darin, eine WinJS.Binding.List zu erstellen. Jede WinJS.Binding.List verfügt über eine dataSource-Eigenschaft, die eine IListDataSource mit Ihren Daten zurückgibt.

    In diesem Beispiel wird eine WinJS.Binding.List aus einer Reihe von JSON-Objekten (myData) erstellt:

    
    // Start of data.js
    (function () {
        "use strict";
    
    
    
        var myData = [
        { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png" },
        { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png" },
        { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png" },
        { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png" },
        { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png" },
        { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png" },
        { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png" },
        { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png" },
        { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png" },
        { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png" },
        { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png" },
        { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png" },
        { title: "Orangy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Orangy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Absolutely Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Absolutely Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Triple Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Triple Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Double Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Double Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Double Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Green Mint", text: "Gelato", picture: "images/60Mint.png" }
        ];
    
        // Create a WinJS.Binding.List from the array. 
        var itemsList = new WinJS.Binding.List(myData);
    

    Hinweis  Diese Daten beziehen sich auf mehrere Bilder. Um die Bilder zu erhalten, laden Sie das Beispiel für ListView-Gruppierung und SemanticZoom herunter, und kopieren Sie die Bilder danach aus dem Beispiel in Ihr Projekt. Sie können auch eigene Bilder verwenden.—Achten Sie in diesem Fall darauf, den Wert der picture-Eigenschaft in Ihren Daten zu aktualisieren.

     

    Tipp  

    Sie müssen nicht immer eine WinJS.Binding.List verwenden. Sie können auch eine benutzerdefinierte VirtualizedDataSource verwenden. (StorageDataSource unterstützt das Gruppieren nicht.) Weitere Informationen zum Erstellen benutzerdefinierter Datenquellen finden Sie unter So wird's gemacht: Erstellen einer benutzerdefinierten Datenquelle.

     

  3. Erstellen Sie eine Version der Datenquelle, die Gruppierungsinformationen enthält. Wenn Sie eine WinJS.Binding.List verwenden, können Sie die createGrouped-Methode aufrufen, um eine gruppierte Version von List zu erstellen.

    Die createGrouped-Methode akzeptiert drei Parameter:

    • getGroupKey: Eine Funktion, die bei Übergabe eines Elements in der Liste den Schlüssel der Gruppe zurückgibt, zu der dieses Element gehört.
    • getGroupData: Eine Funktion, die bei Übergabe eines Elements in der Liste das Datenobjekt zurückgibt, das die Gruppe darstellt, zu der das Element gehört.
    • compareGroups: Eine Funktion, die zum Sortieren von Gruppen verwendet wird, sodass Gruppe A vor Gruppe B kommt. Die Funktion empfängt zwei Gruppenschlüssel als Eingabe, vergleicht die beiden Gruppen und gibt einen der folgenden Werte zurück: einen Wert kleiner Null, wenn die erste Gruppe kleiner als die zweite Gruppe ist, Null, wenn die beiden Gruppe gleich sind, und einen positiven Wert, wenn die erste Gruppe größer als die zweite Gruppe ist.

    Die createGrouped-Methode gibt eine WinJS.Binding.List zurück, die zwei Projektionen der Daten aus der ursprünglichen, nicht gruppierten Liste enthält. Die Projektionen sind dynamisch. Falls Sie die Liste ändern, müssen Sie daher das Original ändern.

    In diesem Beispiel wird die List.createGrouped-Methode verwendet, um eine gruppierte Version der List zu erstellen. Darin werden die Gruppen durch die ersten Buchstaben der einzelnen Elementüberschriften definiert.

        // Sorts the groups
        function compareGroups(leftKey, rightKey) {
            return leftKey.charCodeAt(0) - rightKey.charCodeAt(0);
        }
    
        // Returns the group key that an item belongs to
        function getGroupKey(dataItem) {
            return dataItem.title.toUpperCase().charAt(0);
        }
    
        // Returns the title for a group
        function getGroupData(dataItem) {
            return {
                title: dataItem.title.toUpperCase().charAt(0)
            };
        }
    
        // Create the groups for the ListView from the item data and the grouping functions
        var groupedItemsList = itemsList.createGrouped(getGroupKey, getGroupData, compareGroups);
    
  4. Stellen Sie sicher, dass Ihre Daten im globalen Gültigkeitsbereich zugänglich sind. So können Sie deklarativ auf die Daten zugreifen (wird in Schritt 2.3 erläutert), wenn Sie Ihre ListView erstellen.

    In diesem Beispiel wird WinJS.Namespace.define verwendet, um den öffentlichen Zugriff auf die gruppierte Liste zu ermöglichen.

        WinJS.Namespace.define("myData",
            {
                groupedItemsList: groupedItemsList
            }); 
    
    
    })(); // End of data.js
    

Schritt 2: Erstellen Sie eine ListView, in der das Rasterlayout verwendet wird.

Erstellen Sie anschließend eine ListView, und verbinden Sie sie mit den Daten.

  1. Fügen Sie im head-Abschnitt der HTML-Seite, die die ListView enthält, einen Verweis auf die Datendatei hinzu, die Sie im vorherigen Schritt erstellt haben.

    
    
        <!-- Your data file. -->
        <script src="/js/data.js"></script>
    
  2. Erstellen Sie im body Ihrer HTML-Datei eine ListView. Legen Sie ihre layout-Eigenschaft auf GridLayout fest.

    
    <div id="groupedListView"
        data-win-control="WinJS.UI.ListView" 
        data-win-options="{layout: {type: WinJS.UI.GridLayout}}"
    ></div>
    
  3. Legen Sie die itemDataSource-Eigenschaft des ListView-Steuerelements auf die Datenquelle für die gruppierten Elemente fest.

    Sie haben in Schritt 1 einen Namespacemember erstellt, der die gruppierten Elemente enthält, die Sie anzeigen möchten: myData.groupedItemsList. Durch Aufrufen dieses Felds wird eine WinJS.Binding.List zurückgegeben Um eine IListDataSource zu erhalten, die von der ListView verwendet werden kann, rufen Sie ihre dataSource-Eigenschaft auf: myData.groupedItemsList.dataSource.

    
    <div id="groupedListView"
        data-win-control="WinJS.UI.ListView" 
        data-win-options="{itemDataSource: myData.groupedItemsList.dataSource, 
            layout: {type: WinJS.UI.GridLayout}}"
    ></div>
    
  4. Legen Sie anschließend die groupDataSource-Eigenschaft des ListView-Steuerelements auf die Datenquelle fest, die die Gruppendaten enthält. Mit der groups-Eigenschaft des List-Objekts erhalten Sie eine weitere List, die die Gruppeninformationen enthält. Um eine IListDataSource zu erhalten, rufen Sie "myData.groupedItemsList.groups.dataSource" auf.

    
    <div id="groupedListView"
        data-win-control="WinJS.UI.ListView" 
        data-win-options="{itemDataSource: myData.groupedItemsList.dataSource, 
            groupDataSource: myData.groupedItemsList.groups.dataSource,
            layout: {type: WinJS.UI.GridLayout}}">
    </div>
    

Führen Sie die App aus. Da Sie keine Elementvorlagen angegeben haben, sind die Daten nicht formatiert:

Eine ListView, die die Rohdaten für eine Gruppe anzeigt.

Schritt 3: Erstellen Sie eine Elementvorlage und eine Gruppenkopfvorlage.

Erstellen Sie auf der HTML-Seite vor der Definition der ListView eine WinJS.UI.Template mit dem Namen "mediumListIconTextTemplate", und legen Sie die itemTemplate-Eigenschaft des ListView-Steuerelements auf den Namen dieser Vorlage fest.


<div id="mediumListIconTextTemplate" 
    data-win-control="WinJS.Binding.Template" 
    style="display: none">
    <div class="mediumListIconTextItem">
        <img class="mediumListIconTextItem-Image" data-win-bind="src: picture" />
        <div class="mediumListIconTextItem-Detail">
            <h4 data-win-bind="innerText: title"></h4>
            <h6 data-win-bind="innerText: text"></h6>
        </div>
    </div>
</div>

<div id="groupedListView"
    data-win-control="WinJS.UI.ListView" 
    data-win-options="{itemDataSource: myData.groupedItemsList.dataSource, 
        itemTemplate: select('#mediumListIconTextTemplate'),
        groupDataSource: myData.groupedItemsList.groups.dataSource,
        layout: {type: WinJS.UI.GridLayout}}">
</div>

(Beachten Sie, dass die Vorlage verschiedene Stile angibt, die wir später definieren.)

Führen Sie die App aus. Die Elemente, jedoch nicht die Gruppenköpfe, werden formatiert.

Eine ListView, die die Rohdaten für eine Gruppe anzeigt.

Schritt 4: Erstellen Sie eine Gruppenkopfvorlage.

Definieren Sie eine WinJS.UI.Template für den Gruppenkopf, und weisen Sie ihr die ID "headerTemplate" zu. Legen Sie die groupHeaderTemplate-Eigenschaft des ListView-Steuerelements auf diese Vorlage fest.


<div id="headerTemplate" data-win-control="WinJS.Binding.Template" 
    style="display: none">
    <div class="simpleHeaderItem">
        <h1 data-win-bind="innerText: title"></h1>
    </div>
</div>

<div id="mediumListIconTextTemplate" 
    data-win-control="WinJS.Binding.Template" 
    style="display: none">
    <div class="mediumListIconTextItem">
        <img class="mediumListIconTextItem-Image" data-win-bind="src: picture" />
        <div class="mediumListIconTextItem-Detail">
            <h4 data-win-bind="innerText: title"></h4>
            <h6 data-win-bind="innerText: text"></h6>
        </div>
    </div>
</div>

<div id="groupedListView"
    data-win-control="WinJS.UI.ListView" 
    data-win-options="{itemDataSource: myData.groupedItemsList.dataSource, 
        itemTemplate: select('#mediumListIconTextTemplate'),
        groupDataSource: myData.groupedItemsList.groups.dataSource,
        groupHeaderTemplate: select('#headerTemplate'),
        layout: {type: WinJS.UI.GridLayout}}">
</div>

Führen Sie die App aus. Die Elemente und die Gruppenköpfe werden formatiert.

Eine ListView, in der gruppierte Daten angezeigt werden.

Schritt 5: Gestalten Sie die Vorlagen aus.

Wenn Sie das Aussehen der Elemente und Gruppenköpfe umfassender steuern möchten, können Sie dem Stylesheet eigene CSS-Formatvorlagen hinzufügen. Die CSS in diesem Beispiel formatiert die Elemente und Gruppenköpfe sowie die ListView selbst.


/* CSS for the ListView */
#groupedListView
{
    width: 600px;
    height: 300px;
    border: solid 2px rgba(0, 0, 0, 0.13);
}

/* Template for headers */
.simpleHeaderItem
{
    width: 50px;
    height: 50px;
    padding: 8px;
}   

/* Template for items */  
.mediumListIconTextItem
{
    width: 282px;
    height: 70px;
    padding: 5px;
    overflow: hidden;
    display: -ms-grid;
}

    .mediumListIconTextItem img.mediumListIconTextItem-Image 
    {
        width: 60px;
        height: 60px;
        margin: 5px;
        -ms-grid-column: 1;
    }

    .mediumListIconTextItem .mediumListIconTextItem-Detail
    {
        margin: 5px;
        -ms-grid-column: 2;
    }

Wenn Sie die App ausführen, werden die Elemente in Gruppen unterteilt:

Eine ListView mit gruppierten Elementen

Zum Formatieren Ihrer Gruppen und Elemente können Sie auch die CSS-Klassen win-groupheader und win-container verwenden. Weitere Informationen finden Sie unter Formatieren der ListView und der zugehörigen Elemente.

Anmerkungen

Sortieren und Filtern von Elementen und Gruppen

WinJS.Binding.List kann Elemente und Gruppen sortieren und filtern. Weitere Informationen finden Sie in den Artikeln zu den Methoden createSorted und createFiltered.

Erstellen einer verkleinerten Ansicht Ihrer Gruppen

Sie wissen jetzt, wie eine gruppierte ListView erstellt wird. Damit verfügen Sie über praktisch alle Informationen, die Sie zum Erstellen einer verkleinerten Ansicht Ihrer Gruppen mithilfe des SemanticZoom-Steuerelements benötigen.

Die verkleinerten und vergrößerten Ansichten des SemanticZoom-Steuerelements

Anweisungen zur Verwendung von SemanticZoom finden Sie unter Schnellstart: Hinzufügen von Steuerelementen vom Typ "SemanticZoom".

Gruppierte "ListView"-Steuerelemente mit interaktiven Headern

Wenn Ihr gruppiertes ListView-Steuerelement interaktive Header enthält, empfehlen wir, die Tastenkombination STRG+ALT+G zu unterstützen und damit die Benutzer zu der Gruppe zu bewegen, in der sie zurzeit navigieren. Dabei sollte sich das gleiche Verhalten ergeben wie beim Klicken oder Tippen auf den Gruppenheader selbst.

Löschen von Gruppen und Durchführen von Bildläufen

Wenn eine Gruppe gelöscht wird, führt das ListView möglicherweise einen Bildlauf zu einer unerwarteten Stelle aus. Rufen Sie daher die ensureVisible-Methode auf, um einen Bildlauf zu einer für die App sinnvollen Position durchzuführen.

Vollständiges Beispiel

Ein vollständiges Beispiel, in dem das Erstellen einer gruppierten "ListView" gezeigt wird, bietet das Beispiel für ListView-Gruppierung und SemanticZoom.

Verwandte Themen

ListView-Gruppierung und SemanticZoom

Schnellstart: Hinzufügen von Steuerelementen vom Typ "SemanticZoom"