Come raggruppare gli elementi in un controllo ListView (HTML)

[ Questo articolo è rivolto agli sviluppatori per Windows 8.x e Windows Phone 8.x che realizzano app di Windows Runtime. Gli sviluppatori che usano Windows 10 possono vedere Documentazione aggiornata ]

Scopri come raggruppare elementi in un controllo ListView. Per visualizzare informazioni sui gruppi, ad esempio intestazioni e limiti, devi usare un layout a griglia per ListView. Per il funzionamento del raggruppamento, la proprietà loadingBehavior del controllo ListView deve essere impostata su "randomaccess" (valore predefinito).

Cosa sapere

Tecnologie

Prerequisiti

Istruzioni

Passaggio 1: Crea i tuoi dati personali

Il raggruppamento richiede due origini dati, IListDataSource che contiene gli elementi, e IListDataSource, che contiene i gruppi. Nell'origine dati degli elementi IListDataSource ogni elemento contiene una proprietà groupKey che lo collega al gruppo a cui appartiene nell'origine dati IListDataSource dei gruppi.

  1. Aggiungi un nuovo file JavaScript al progetto per contenere i tuoi dati. Assegnagli il nome "data.js".

  2. Nel file data.js appena creato, crea l'origine dati sottostante che fornirà dati al controllo ListView.

    Per creare IListDataSource, puoi creare WinJS.Binding.List. Ogni WinJS.Binding.List ha una proprietà dataSource che restituisce un oggetto IListDataSource contenente i tuoi dati.

    Questo esempio crea un oggetto WinJS.Binding.List da una matrice di oggetti JSON (myData):

    
    // 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);
    

    Nota  Questi dati fanno riferimento a diverse immagini. Per ottenere le immagini, scarica l'esempio di raggruppamento del controllo ListView e SemanticZoom, poi copia le immagini dall'esempio nel tuo progetto. Puoi anche usare le tue immagini — assicurandoti solo di aggiornare il valore della proprietà picture nei tuoi dati.

     

    Suggerimento  

    Non sei obbligato a usare un oggetto WinJS.Binding.List: puoi usare anche un oggetto VirtualizedDataSource personalizzato (StorageDataSource non supporta il raggruppamento). Per altre informazioni sulla creazione di un'origine dati personalizzata, vedi Come creare un'origine dati personalizzata.

     

  3. Crea una versione dell'origine dati che contenga info sul raggruppamento. Se usi WinJS.Binding.List, puoi chiamare il relativo metodo createGrouped per creare una versione raggruppata di List.

    Il metodo createGrouped accetta 3 parametri:

    • getGroupKey: una funzione che, dato un elemento nell'elenco, restituisce una chiave di gruppo a cui appartiene l'elemento.
    • getGroupData: funzione che, dato un elemento nell'elenco, restituisce l'oggetto dati che rappresenta il gruppo a cui appartiene l'elemento.
    • compareGroups: funzione usata per ordinare i gruppi in modo che il gruppo A venga prima del gruppo B. La funzione accetta due chiavi di gruppo come input, confronta i due gruppi e restituisce un valore minore di zero se il primo gruppo è minore del secondo, uguale a zero se i gruppi sono identici e un valore positivo se il primo gruppo è maggiore del secondo.

    Il metodo createGrouped restituisce un oggetto WinJS.Binding.List contenente due proiezioni dei dati provenienti dall'elenco originale non raggruppato. Le proiezioni sono dinamiche, per cui le modifiche apportate all'elenco si riflettono anche nell'originale.

    Questo esempio usa il metodo List.createGrouped per creare una versione raggruppata del controllo List. I gruppi vengono definiti basandosi sulla prima lettera del titolo di ogni elemento.

        // 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. Rendi i tuoi dati accessibili dall'ambito globale. In questo modo, quando crei ListView, puoi accedere ai dati in modo dichiarativo (come illustreremo nel passaggio 2.3).

    Questo esempio usa WinJS.Namespace.define per rendere pubblicamente accessibile l'elenco raggruppato.

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

Passaggio 2: Crea un controllo ListView che usa il layout a griglia.

Crea quindi un controllo ListView e collegalo ai tuoi dati.

  1. Nella sezione head della tua pagina HTML che contiene ListView, aggiungi un riferimento al file di dati creato nel passaggio precedente.

    
    
        <!-- Your data file. -->
        <script src="/js/data.js"></script>
    
  2. Nella sezione body del file HTML, crea un oggetto ListView. Imposta la proprietà layout su GridLayout.

    
    <div id="groupedListView"
        data-win-control="WinJS.UI.ListView" 
        data-win-options="{layout: {type: WinJS.UI.GridLayout}}"
    ></div>
    
  3. Imposta la proprietà itemDataSource del controllo ListView sull'origine dati degli elementi raggruppati.

    Nel passaggio 1, hai creato un membro dello spazio dei nomi contenente gli elementi raggruppati che vuoi visualizzare: myData.groupedItemsList. Chiamando questo campo viene restituito WinJS.Binding.List. Per ottenere IListDataSource che ListView possa usare, chiama la proprietà dataSource: 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. Imposta quindi la proprietà groupDataSource del controllo ListView sull'origine dati contenente i dati del gruppo. Usa la proprietà groups dell'oggetto List per ottenere un altro List contenente le informazioni sul gruppo. Per ottenere IListDataSource, chiama myData.groupedItemsList.groups.dataSource.

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

Esegui l'app. Dato che non hai specificato modelli di elemento, i dati non sono formattati:

Un controllo ListView che visualizza i dati non elaborati di un gruppo.

Passaggio 3: Crea un modello di elemento e un modello di intestazione del gruppo

Nella pagina HTML, prima di definire il controllo ListView, crea un elemento WinJS.UI.Template denominato "mediumListIconTextTemplate" e imposta la proprietà itemTemplate del controllo ListView nel nome di questo modello.


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

(nota che il modello specifica più stili, che verranno definiti in seguito).

Esegui l'app. Gli elementi, ma non le intestazioni del gruppo, sono formattati.

ListView che visualizza i dati non elaborati per un gruppo.

Passaggio 4: Crea un modello di intestazioni di gruppo

Definisci WinJS.UI.Template per l'intestazione di gruppo e assegna un ID di "headerTemplate". Imposta la proprietà groupHeaderTemplate del controllo ListView in questo modello.


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

Esegui l'app. Gli elementi e le intestazioni di gruppo sono ora formattate.

Un controllo ListView che visualizza dati raggruppati.

Passaggio 5: Crea i tuoi modelli

Se vuoi specificare più nel dettaglio l'aspetto dei tuoi elementi e delle tue intestazioni, puoi creare stili CSS per il foglio di stile. Lo stile CSS in questo esempio viene applicato agli elementi, alle intestazioni e allo stesso controllo ListView.


/* 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;
    }

Quando esegui l'app, gli elementi vengono divisi in gruppi:

Un controllo ListView con elementi raggruppati

Puoi anche usare le classi CSS win-groupheader e win-container per applicare stili ai gruppi e agli elementi. Per altre informazioni vedi Applicazione di stili a un controllo ListView e ai relativi elementi.

Osservazioni

Ordinamento e filtri di elementi e gruppi

WinJS.Binding.List può ordinare e filtrare gli elementi e i gruppi. Per altre informazioni, vedi i metodi createSorted e createFiltered.

Creare una visualizzazione ridotta dei gruppi

Ora che sai come creare un controllo ListView raggruppato, non ti serve molto altro per usare il controllo SemanticZoom per creare una visualizzazione ridotta dei gruppi.

Visualizzazioni ingrandite e ridotte di un controllo SemanticZoom

Per istruzioni su come usare SemanticZoom, vedi Guida introduttiva: Aggiunta dei controlli SemanticZoom.

Controlli ListView raggruppati che contengono intestazioni interattive

Quando il tuo controllo ListView raggruppato contiene intestazioni interattive, ti consigliamo di supportare il tasto di scelta rapida CTRL+ALT+G e di usarlo per consentire lo spostamento dell'utente nel gruppo che sta attualmente esplorando. Il comportamento di questo tasto di scelta rapida deve essere uguale a quello ottenuto facendo clic o toccando l'intestazione del gruppo.

Eliminazione di gruppi e scorrimento

Quando un gruppo viene eliminato, è possibile che il controllo ListView scorra fino a una posizione imprevista. Chiama quindi il metodo ensureVisible per fare in modo che il controllo scorra fino a una posizione significativa per l'app.

Esempio completo

Per un esempio completo che mostra come creare un controllo ListView raggruppato, vedi l'esempio Raggruppamento del controllo ListView e SemanticZoom.

Argomenti correlati

Raggruppamento del controllo ListView e SemanticZoom

Guida introduttiva: Aggiunta di controlli SemanticZoom