Condividi tramite


Come visualizzare elementi di dimensioni diverse (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 ]

Per impostazione predefinita, ListView alloca le stesse dimensioni per ogni elemento dell'elenco. Se usi un layout a griglia, puoi modificare questo comportamento e visualizzare elementi di dimensioni diverse estendendoli in più celle.

Cosa sapere

Tecnologie

Prerequisiti

Istruzioni

Informazioni sulle celle e sul ridimensionamento in ListView

Prima di entrare nel codice, è utile capire in che modo ListView gestisce il ridimensionamento degli elementi.

Per impostazione predefinita, ListView alloca le stesse dimensioni di cella per ogni elemento dell'elenco. Ecco un controllo ListView contenente tutti elementi delle stesse dimensioni.

Controllo ListView contenente elementi della stessa dimensione

Ecco lo stesso controllo ListView con una singola cella evidenziata.

Cella in un controllo ListView

Le dimensioni della cella sono determinate dalle dimensioni del primo elemento in ListView. Se ListView contiene elementi di dimensioni diverse, alloca comunque le dimensioni della cella in base alle dimensioni del primo elemento. Pertanto, se un elemento è più grande degli altri, verrà troncato in modo che corrisponda alle dimensioni degli altri elementi di ListView.

Controllo ListView contenente elementi di dimensini diverse

Puoi modificare questo comportamento abilitando l'estensione in più celle. In questo caso, un elemento può occupare più celle. In questo esempio l'estensione in più celle è attivata in modo che l'elemento più grande occupi cinque celle anziché una.

Controllo ListView con estensione in più celle attivata

Se attivi l'estensione in più celle, puoi anche specificare esplicitamente le dimensioni della cella di base. È consigliabile che le dimensioni di ogni elemento di ListView siano un multiplo delle dimensioni della cella di base. Nell'esempio successivo l'elemento più grande viene modificato in modo che abbia un'altezza doppia rispetto a quella della cella di base, ma la stessa larghezza.

Controllo ListView con elementi che sono multipli della stessa dimensione di cella di base

Ecco come creare un controllo ListView contenente elementi di tre dimensioni diverse.

Passaggio 1: Creare i dati e ListView

Creiamo innanzitutto un'origine dati e un controllo ListView.

  1. In un file JavaScript definiamo un'origine dati per ListView. In questo esempio creiamo un oggetto List da una matrice di oggetti JSON e lo rendiamo pubblicamente accessibile usando WinJS.Namespace.define per esporlo tramite uno spazio dei nomi denominato DataExamples.

    I dati sono simili a quelli degli esempi riportati in altri argomenti, ad esempio in Guida introduttiva: Aggiunta di un controllo ListView, con l'unica aggiunta di un campo type. Questo campo può avere tre valori, ovvero "smallListIconTextItem", "mediumListIconTextItem" e "largeListIconTextItem". Nei passaggi successivi usiamo questo campo per assegnare una classe CSS che determina le dimensioni di ogni elemento.

    (function () {
        "use strict";
    
        var myCellSpanningData = new WinJS.Binding.List([
                { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png", type: "smallListIconTextItem" },
                { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png", type: "mediumListIconTextItem" },
                { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png", type: "largeListIconTextItem" },
                { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png", type: "mediumListIconTextItem" },
                { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png", type: "smallListIconTextItem" },
                { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png", type: "smallListIconTextItem" },
                { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png", type: "mediumListIconTextItem" },
                { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png", type: "mediumListIconTextItem" },
                { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png", type: "smallListIconTextItem" },
                { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png", type: "smallListIconTextItem" },
                { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png", type: "smallListIconTextItem" },
                { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png", type: "smallListIconTextItem" },
                { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png", type: "smallListIconTextItem" },
                { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png", type: "smallListIconTextItem" },
                { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png", type: "mediumListIconTextItem" },
                { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png", type: "smallListIconTextItem" },
                { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png", type: "largeListIconTextItem" },
                { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png", type: "mediumListIconTextItem" }
        ]);
    
    
    
        WinJS.Namespace.define("DataExamples",
            {
                myCellSpanningData: myCellSpanningData
            });
    
    })();
    

    Se scrivi il codice mentre leggi e vuoi usare le immagini dell'esempio, puoi trovarle scaricando l'esempio di modelli di elementi di ListView.

  2. Nel file HTML creiamo un controllo ListView che usa il layout con estensione in più celle. Impostiamo la proprietà itemDataSource sull'origine dati creata nel passaggio precedente.

    <div id="myListView" 
        data-win-control="WinJS.UI.ListView" 
        data-win-options="{ 
            itemDataSource: DataExamples.myCellSpanningData.dataSource, 
            layout: {  
                type: WinJS.UI.CellSpanningLayout 
            } 
        }"
    ></div>
    

Passaggio 2: Definire le dimensioni della cella di base e abilitare l'estensione in più celle

A questo punto dobbiamo definire le dimensioni della cella di base.

Per impostare ListView in modo che usi un layout con estensione in più celle, creiamo un oggetto CellSpanningLayout e lo usiamo per impostare la proprietà layout del controllo ListView. Per attivare l'estensione in più celle e definire le dimensioni della cella di base, creiamo una funzione groupInfo che fornisce queste informazioni e la usiamo per impostare la proprietà groupInfo dell'oggetto CellSpanningLayout. La funzione groupInfo che definiamo deve restituire un oggetto contenente queste proprietà:

  • enableCellSpanning
    Da impostare su true per attivare l'estensione in più celle. Il valore predefinito è false.

  • cellWidth
    Larghezza della cella di base.

  • cellHeight
    Altezza della cella di base.

Per questo esempio, useremo una cella di base di dimensioni pari a 310×80 pixel.

JJ657974.wedge(it-it,WIN.10).gifPer definire le dimensioni della cella di base e abilitare l'estensione in più celle

  1. Nel file JavaScript in cui abbiamo creato i dati, creiamo una funzione groupInfo che attiva l'estensione in più celle e definisce le dimensioni della cella di base pari a 310×80 pixel.

    // Enable cell spanning and specify
    // the cellWidth and cellHeight for the items
    var groupInfo = function groupInfo() {
        return {
            enableCellSpanning: true,
            cellWidth: 310,
            cellHeight: 80
        };
    };
    
  2. Usiamo WinJS.Utilities.markSupportedForProcessing per rendere la funzione accessibile in HTML.

    // Enable cell spanning and specify
    // the cellWidth and cellHeight for the items
    var groupInfo = function groupInfo() {
        return {
            enableCellSpanning: true,
            cellWidth: 310,
            cellHeight: 80
        };
    };
    
    WinJS.Utilities.markSupportedForProcessing(groupInfo);
    

    Per impostazione predefinita, le funzioni e i gestori eventi non sono accessibili ai controlli della libreria Windows per JavaScript, per motivi di sicurezza. La funzione WinJS.Utilities.markSupportedForProcessing consente di ignorare questo comportamento predefinito. Questo presuppone che il codice HTML che fornisci sia in formato corretto e possa essere elaborato da WinJS. Per altre informazioni, vedi Codifica di app di base.

    La chiamata a WinJS.Utilities.markSupportedForProcessing nella funzione non la rende pubblicamente accessibile. Eseguiremo questa operazione nel prossimo passaggio.

  3. Rendiamo pubblicamente accessibile la funzione groupInfo esponendola tramite uno spazio dei nomi. In questo esempio aggiorniamo lo spazio dei nomi DataExamples creato nel passaggio 1.1.

    WinJS.Namespace.define("DataExamples",
        {
            groupInfo : groupInfo,
            myCellSpanningData: myCellSpanningData
        });
    
  4. Aggiorniamo ListView per usare la funzione groupInfo.

    <div id="myListView" 
        data-win-control="WinJS.UI.ListView" 
        data-win-options="{ 
            itemDataSource: DataExamples.myCellSpanningData.dataSource, 
            layout: {  
                groupInfo: DataExamples.groupInfo,
                type: WinJS.UI.GridLayout 
            } 
        }"
    ></div>
    

Passaggio 3: Definire le dimensioni di un elemento che si estende in un'unica cella

Dopo aver definito le dimensioni della cella di base, possiamo definire quelle degli elementi. Quando abbiamo definito i dati nel primo passaggio, abbiamo incluso un campo type contenente informazioni sulle dimensioni dell'elemento, ossia se devono essere piccole, medie o grandi. Possiamo usare queste informazioni per assegnare le dimensioni agli elementi. Il modo migliore per assegnare le dimensioni consiste nell'usare le classi CSS. Questo approccio è efficace sia se usiamo una funzione di modello o WinJS.Binding.Template.

Le dimensioni della cella di base sono pari a 310 pixel in larghezza e 80 pixel in altezza. Le dimensioni totali di ogni elemento devono essere un multiplo delle dimensioni della cella di base. Le dimensioni della cella di base corrispondono alle dimensioni dell'elemento più il relativo riempimento, il margine e il bordo:

Cella in un controllo ListView

Ecco la formula per calcolare le dimensioni della cella di base:

  • Larghezza cella di base = larghezza elemento + riempimento orizzontale elemento + margine orizzontale elemento + spessore bordo elemento
  • Altezza cella di base = altezza elemento + riempimento verticale elemento + margine verticale elemento + spessore bordo elemento

JJ657974.wedge(it-it,WIN.10).gifPer definire le dimensioni di un elemento che occupa un'unica cella di base

  1. Definiamo le dimensioni dell'elemento più piccolo. Nel file CSS creiamo una classe CSS (Cascading Style Sheet) denominata "smallListIconTextItem".

    .smallListIconTextItem
    {
    
    }     
    
  2. L'elemento più piccolo occupa un'unica cella. Impostiamo la larghezza dell'elemento su 300 px, l'altezza su 70 px e il riempimento su 5 px.

    .smallListIconTextItem
    {
        width: 300px;
        height: 70px;
        padding: 5px;
        overflow: hidden;
        background-color: Pink;
        display: -ms-grid;
    }    
    

    Confrontiamo questi numeri con la nostra formula per verificare che corrispondano alle dimensioni della cella di base.

    • Larghezza cella = larghezza elemento + riempimento sinistro + riempimento destro + spessore bordo + margine sinistro + margine destro = 300 + 5 px + 5 px + 0 + 0 + 0 = 310

    • Altezza cella = altezza elemento + riempimento superiore + riempimento inferiore + spessore bordo + margine superiore + margine inferiore = 70 px+ 5 px + 5 px + 0 + 0 + 0 = 80

    Queste misure corrispondono alle dimensioni della cella di base, quindi possiamo procedere al passaggio successivo.

Passaggio 4: Definire le dimensioni di un elemento che si estendono in due o più celle

Per determinare le dimensioni di un elemento che si estende in una o più celle, devi tenere conto anche del margine win-container tra le celle che occupa. Se ad esempio un elemento si estende in una cella in orizzontale e in due in verticale, le dimensioni totali includono il margine inferiore win-container della prima cella e il margine superiore win-container della seconda, come illustrato qui:

Elemento che si estende in due celle

Ecco la formula per calcolare le dimensioni totali di un elemento che si estende in più celle:

  • Larghezza totale elemento = number of cells * larghezza cella di base + (number of cells - 1) * (margine sinistro win-container + margine destro win-container)

  • Altezza totale elemento = number of cells * altezza cella di base + (number of cells - 1) * (margine superiore win-container + margine inferiore win-container)

Suggerimento  Il margine win-container è pari a 5 pixel per impostazione predefinita.

 

JJ657974.wedge(it-it,WIN.10).gifPer definire le dimensioni di un elemento che si estende in due celle in verticale

  1. Usiamo la nostra formula per determinare l'altezza totale dell'elemento:

    Altezza totale elemento = number of cells * altezza cella di base + (number of cells - 1) * (margine superiore win-container + margine inferiore win-container) = 2 * 80 + (2-1) * (5 + 5) = 170

  2. Creiamo lo stile CSS che specifica l'elemento dimensioni. In questo esempio definiamo un elemento con un'altezza di 160 pixel e un riempimento di 5 pixel, per un'altezza totale pari a 160 + 5 + 5 = 170. Poiché l'elemento si estende in un'unica cella in orizzontale, assegniamo la stessa larghezza e lo stesso riempimento della classe CSS creata nel passaggio 3, smallListIconTextItem.

    .mediumListIconTextItem
    {
        width: 300px;
        height: 160px;
        padding: 5px;
        overflow: hidden;
        background-color: LightGreen;
        display: -ms-grid;
    }
    

JJ657974.wedge(it-it,WIN.10).gifPer definire le dimensioni di un elemento che si estende in tre celle in verticale

  1. Usiamo la nostra formula per determinare l'altezza totale dell'elemento:

    Altezza totale elemento = number of cells * altezza cella di base + (number of cells - 1) * (margine superiore win-container + margine inferiore win-container) = 3 * 80 + (3-1) * (5 + 5) = 260

  2. Creiamo lo stile CSS che specifica l'elemento dimensioni. In questo esempio definiamo un elemento con un'altezza di 250 pixel e un riempimento di 5 pixel, per un'altezza totale pari a 250 + 5 + 5 = 260.

    .largeListIconTextItem
    {
        width: 300px;
        height: 250px;
        padding: 5px;
        overflow: hidden;
        background-color: LightBlue;
        display: -ms-grid;
    }
    

Passaggio 5: Creare la funzione di dimensionamento degli elementi per CellSpanningLayout

Oltre alla funzione groupInfo, l'oggetto CellSpanningLayout deve esporre una funzione itemInfo che determini la modalità di dimensionamento degli elementi di "tipi" diversi nell'origine dati. La funzione itemInfo deve restituire un oggetto JavaScript contenente queste proprietà:

  • width
    La larghezza del singolo elemento in ListView.

  • height
    L'altezza del singolo elemento in ListView.

JJ657974.wedge(it-it,WIN.10).gifPer definire le dimensioni dei singoli elementi in ListView

  1. Nel file JavaScript in cui abbiamo creato i dati, creiamo ora una funzione itemInfo che recuperi un elemento dall'origine dati e restituisca le dimensioni corrispondenti e l'altezza di tale elemento.

    // Item info function that returns the size of a cell spanning item
    var itemInfo = WinJS.Utilities.markSupportedForProcessing(function itemInfo(itemIndex) {
        var size = { width: 310, height: 80 };
    
        // Get the item from the data source
        var item = DataExamples.myCellSpanningData.getAt(itemIndex);
        if (item) {
    
            // Get the size based on the item type
            switch (item.type) {
                case "smallListIconTextItem":
                    size = { width: 310, height: 80 };
                    break;
    
                case "mediumListIconTextItem":
                    size = { width: 310, height: 170 };
                    break;
    
                case "largeListIconTextItem":
                    size = { width: 310, height: 260 };
                    break;
    
                default:
            }
        }
        return size;
    });
    

    Viene eseguito il wrapping di itemInfo tramite una chiamata a WinJS.Utilities.markSupportedForProcessing per rendere accessibile la funzione in HTML.

  2. Rendiamo pubblicamente accessibile la funzione itemInfo esponendola tramite uno spazio dei nomi. In questo esempio aggiorniamo lo spazio dei nomi DataExamples creato nel passaggio 1.1.

    WinJS.Namespace.define("DataExamples",
        {
            myCellSpanningData: myCellSpanningData,
            groupInfo: groupInfo,
            itemInfo: itemInfo
    });
    
  3. Aggiorniamo ListView per usare la funzione itemInfo.

    <div id="myListView" 
        data-win-control="WinJS.UI.ListView" 
        data-win-options="{ 
            itemDataSource: DataExamples.myCellSpanningData.dataSource, 
            layout: {  
                groupInfo: DataExamples.groupInfo,
                itemInfo: DataExamples.itemInfo,
                type: WinJS.UI.CellSpanningLayout
            } 
        }"
    ></div>
    

Passaggio 6: Creare il modello

Il passaggio finale consiste nel creare un modello o una funzione di modello che usa le classi CSS appena definite. Illustreremo come creare un oggetto WinJS.Binding.Template e una funzione di modello.

JJ657974.wedge(it-it,WIN.10).gifOpzione A: Usare WinJS.Binding.Template

  1. Definiamo nel codice HTML un oggetto WinJS.Binding.Template.

    <div id="myItemTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
        <div>
            <img src="#" class="regularListIconTextItem-Image" data-win-bind="src: picture" />
            <div class="regularListIconTextItem-Detail">
                <h4 data-win-bind="innerText: title"></h4>
                <h6 data-win-bind="innerText: text"></h6>
            </div>
         </div>
     </div>
    
  2. Ricordiamo che, quando abbiamo definito i dati nel passaggio 1.1, abbiamo incluso una proprietà type che specifica quale classe CSS verrà assegnata a ogni elemento. Ora possiamo usare questi dati. Nell'elemento radice dell'elemento, associamo il nome della classe al valore del campo type dei dati.

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

    Nota  Nell'esempio eseguiamo l'associazione a className, non a class, perché, anche se usiamo "class" in HTML, la proprietà JavaScript di supporto è denominata "className". Quando l'app elabora l'attributo data-win-bind, assegna i valori associati mediante chiamate JavaScript.

    Ciò significa che, ogni volta che il nome dell'attributo HTML è diverso dal nome della proprietà JavaScript di supporto, è necessario usare il nome della proprietà JavaScript per impostare data-win-bind.

     

  3. Aggiorniamo ListView in modo da usare il modello impostando la relativa proprietà itemTemplate sull'ID del modello.

    <div id="listView"
         data-win-control="WinJS.UI.ListView"
         data-win-options="{
             itemDataSource: DataExamples.myCellSpanningData.dataSource,
             itemTemplate: select(#'myItemTemplate'),
             layout: {
                 groupInfo: DataExamples.groupInfo,
                 itemInfo: DataExamples.itemInfo,
                 type: WinJS.UI.CellSpanningLayout
        }
    }"></div
    

Se vuoi, puoi usare una funzione di modello invece di WinJS.Binding.Template. L'uso di una funzione di modello può offrirti una maggiore flessibilità nella generazione del codice HTML e nell'assegnazione delle dimensioni.

JJ657974.wedge(it-it,WIN.10).gifOpzione B: Usare una funzione di modello

  1. Definiamo la funzione di modello in un file JavaScript. Puoi aggiungere questo codice allo stesso file contenente i dati oppure a un file diverso. Verifica solo che la pagina che contiene ListView faccia riferimento a questo file.

    In questo esempio usiamo i dati type per ogni elemento in modo da assegnarlo alla classe CSS che ne determina le dimensioni.

    var myCellSpanningJSTemplate = function myCellSpanningJSTemplate(itemPromise) {
        return itemPromise.then(function (currentItem) {
            var result = document.createElement("div");
    
            // Use source data to decide what size to make the
            // ListView item
            result.className = currentItem.data.type;
            result.style.overflow = "hidden";
    
            // Display image
            var image = document.createElement("img");
            image.className = "regularListIconTextItem-Image";
            image.src = currentItem.data.picture;
            result.appendChild(image);
    
            var body = document.createElement("div");
            body.className = "regularListIconTextItem-Detail";
            body.style.overflow = "hidden";
            result.appendChild(body);
    
            // Display title
            var title = document.createElement("h4");
            title.innerText = currentItem.data.title;
            body.appendChild(title);
    
            // Display text
            var fulltext = document.createElement("h6");
            fulltext.innerText = currentItem.data.text;
            body.appendChild(fulltext);
    
            return result;
        });
    };
    
  2. Chiamiamo markSupportedForProcessing nella funzione in modo che sia accessibile mediante markup.

    WinJS.Utilities.markSupportedForProcessing(myCellSpanningJSTemplate);
    
  3. In questo esempio usiamo WinJS.Namespace.define per rendere la funzione pubblicamente accessibile.

    WinJS.Namespace.define("Templates",
        {
            myCellSpanningJSTemplate: myCellSpanningJSTemplate
        });
    
  4. Nel codice HTML aggiorniamo ListView in modo da usare la funzione di modello impostando la relativa proprietà itemTemplate sul nome della funzione di modello.

    <div id="myListView" 
        data-win-control="WinJS.UI.ListView" 
        data-win-options="{ 
            itemDataSource: DataExamples.myCellSpanningData.dataSource,
            itemTemplate:  Templates.myCellSpanningJSTemplate
            layout: {  
                groupInfo: DataExamples.groupInfo,
                itemInfo: DataExamples.itemInfo,
                type: WinJS.UI.CellSpanningLayout
            } 
        }"
    ></div>
    

Indipendentemente dall'approccio adottato, quando esegui l'app, ListView visualizza elementi di dimensioni diverse.

ListView con elementi di dimensioni diverse

Osservazioni

Modifica degli elementi

Quando modifichi gli elementi in un controllo ListView con l'estensione in più celle abilitata, chiama ListView.recalculateItemPosition ogni volta che apporti una modifica.

Argomenti correlati

Esempio di modelli di elementi di ListView