Condividi tramite


Come abilitare il riordinamento, il trascinamento e il rilascio per un controllo ListView

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

Informazioni su come aggiungere funzionalità per riordinare, trascinare e rilasciare elementi in un controllo ListView. (solo Windows)

Cosa sapere

Tecnologie

Prerequisiti

Istruzioni

Passaggio 1: Impostare l'esempio

Questo esempio dimostra come creare un controllo ListView e un oggetto ItemContainer per visualizzare info su un elemento nell'elenco.

Usa il markup HTML seguente come base per il controllo ListView. Puoi copiare e incollare il codice nel file default.html in un'app vuota in Microsoft Visual Studio 2013.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>List_View_demo</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.2.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.2.0/js/ui.js"></script>

    <!-- List_View_demo references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
    <script src="js/data.js"></script>
</head>
<body>
    <div id="listViewTemplate">
        <div id="listTemplate" 
            data-win-control="WinJS.Binding.Template">
            <div class="listTemplate">
                <div>
                    <h4 data-win-bind="innerText: title"></h4>
                    <h6 data-win-bind="innerText: text"></h6>
                </div>
            </div>
        </div>
        <div id="listView" 
             data-win-control="WinJS.UI.ListView"
             data-win-options="{
                itemDataSource : DataExample.itemList.dataSource,
                itemTemplate: select('#listTemplate'),
                itemsDraggable: true,
                itemsReorderable: true,
                layout: { type: WinJS.UI.GridLayout }
             }">
        </div>
    </div>
    <div id="listViewDetail" >
        <h2>Details</h2><br/><br/>
        <div id="listViewDetailInfo" 
             draggable="true"
             data-win-control="WinJS.UI.ItemContainer">
            <h4>Cherry chocolate swirl</h4>
            <h6>Ice cream</h6>
            <p>Description: 
                <span>A sumptious blending of cherry 
                and dark chocolate.</span>
            </p>
        </div>
    </div>
</body>
</html>

L'esempio usa anche gli stili CSS per adattare il controllo ListView e ItemContainer nella pagina HTML. Aggiungi il codice CSS seguente al foglio di stile associato al controllo ListView (css/default.css nel modello Applicazione vuota).


/* Layout the app page as a grid. */
body {
    display: -ms-grid;
    -ms-grid-columns: 600px 1fr;
    -ms-grid-rows: 1fr;
}

/* Style the template for the ListView control.
.listTemplate {
    width: 282px;
    height: 70px;
    padding: 5px;
    overflow: hidden;
}

.listTemplate div {
    margin: 5px;
}

/* Style the ListView control. */
#listView {
    -ms-grid-column: 1;
    -ms-grid-row: 1;
    height: 500px; 
    width: 500px; 
    border: 2px solid gray;
}

#listView .win-container {
    margin: 10px;
}

#listView .win-container:hover {
    color: red;
}

/* Style the ItemContainer control.*/
#listViewDetail {
    -ms-grid-column: 2;
    -ms-grid-row: 1;
}

#listViewDetailInfo {
    width: 300px;
}

L'esempio usa alcuni dati predefiniti per popolare il controllo ListView. I dati sono contenuti in un file denominato 'data.js' nella cartella js (js/data.js). Usa le istruzioni seguenti per aggiungere i dati ListView all'app.

Dn423315.wedge(it-it,WIN.10).gifPer aggiungere un file di dati JavaScript all'app

  1. In Esplora soluzioni fai clic con il pulsante destro del mouse sulla cartella js e scegli Aggiungi > Nuovo file JavaScript.

  2. Nella casella Nome della finestra di dialogo Aggiungi nuovo elemento digita 'data.js' e quindi fai clic su Aggiungi.

  3. In Esplora soluzioni fai doppio clic sul nuovo file JavaScript e aggiungi il codice seguente.

    (function () {
        "use strict";
    
        // Define the dataset.
        var dataArray = [
            { title: "Basic banana", 
              text: "Low-fat frozen yogurt", 
              description: "Go bananas for some frozen yogurt." },
            { title: "Banana blast", 
              text: "Ice cream", 
              description: "More banana than allowed by law." },
            { title: "Brilliant banana", 
              text: "Frozen custard", 
              description: "Custard with banana; an excellent desert." },
            { title: "Orange surprise", 
              text: "Sherbet", 
              description: "Orange sherbert with a little extra something." },
            { title: "Original orange", 
              text: "Sherbet", 
              description: "The orange sherbert you know and love." },
            { title: "Vanilla", 
              text: "Ice cream", 
              description: "The one and only, classic vanilla ice cream." },
            { title: "Very vanilla", 
              text: "Frozen custard", 
              description: "What's better than custard with vanilla flavoring?" },
            { title: "Marvelous mint", 
              text: "Gelato", 
              description: "Mint meets gelato in this delicious desert." },
            { title: "Succulent strawberry", 
              text: "Sorbet", 
              description: "A joyful confection of strawberries." }
        ];
    
        // Load the dataset into a List object.
        var dataList = new WinJS.Binding.List(dataArray);
    
        // Expose the List object to the rest of the app.
        WinJS.Namespace.define("DataExample", {
            itemList: dataList
        });
    
    })();
    

Nota  Puoi sostituire i dati specificati con quelli necessari. Per sostituire l'origine dati, puoi modificare il set di dati passato al metodo costruttore WinJS.Binding.List.

Se decidi di usare un'origine dati diversa da un oggetto IListDataSource, l'origine dati deve implementare i metodi moveBefore, moveAfter e moveToStart. In pratica, ti consigliamo di usare l'oggetto List fornito da WinJS per il wrapping dell'origine dati.

Nota anche che l'oggetto Template definito nel markup HTML per l'app accetta un'origine dati che contiene elementi con le proprietà title e text. Se i dati non contengono proprietà title o text, devi adattare la definizione dell'oggetto Template.

 

Passaggio 2: Aggiungere funzionalità di riordinamento al controllo ListView

È molto semplice aggiungere funzionalità di riordinamento a un controllo ListView. È necessaria una semplice modifica o aggiunta nel codice. Fondamentalmente devi solamente impostare la proprietà itemsReorderable per il controllo ListView su 'true'. (L'impostazione predefinita è 'false'.)

Puoi eseguire questa operazione in modo dichiarativo nel markup HTML per il controllo oppure puoi aggiungere questa funzionalità in fase di esecuzione con JavaScript. L'esempio seguente dimostra come aggiungere la funzionalità di riordinamento adattando il markup HTML per il controllo.

<!-- The definition of the ListView control. 
    Note that the data-win-options attribute for the 
    control includes the itemsReorderable property. -->
<div id="listView"
    data-win-control="WinJS.UI.ListView"
    data-win-options="{
        itemDataSource : DataExample.itemList.dataSource,
        itemTemplate: select('#listTemplate'),
        itemsReorderable : true,
        layout: { type : WinJS.UI.GridLayout }
    }">
</div>

Il prossimo esempio dimostra come aggiungere la funzionalità di riordinamento a un controllo ListView in fase di esecuzione tramite JavaScript.

(function () {

    // Other JavaScript code ...

    // Get a reference to the ListView control.
    var listView = 
        document.querySelector('#listView').winControl;

    // Set the controls itemsReorderable property.
    listView.itemsReorderable = true;

    // Other JavaScript code ...

})();

Dopo aver modificato la proprietà itemsReorderable per il controllo ListView, esegui il progetto (premi F5). Seleziona un elemento in ListView e trascinalo in un'altra posizione nello stesso ListView.

Passaggio 3: Aggiungere la funzionalità di trascinamento in un controllo ListView

Di base, puoi aggiungere la funzionalità di trascinamento a un controllo ListView con la stessa facilità con cui è possibile aggiungere la funzionalità di riordinamento. Il controllo ListView contiene una proprietà itemsDraggable che puoi impostare in modo dichiarativo nel codice HTML del controllo oppure che puoi modificare in fase di esecuzione.

Il prossimo esempio mostra come aggiungere una semplice funzionalità di trascinamento a un controllo ListView nel markup HTML per il controllo.

<!-- The definition of the ListView control. 
    Note that  the data-win-options attribute for the 
    control includes the itemsDraggable property. -->
<div id="listView"
    data-win-control="WinJS.UI.ListView"
    data-win-options="{
        itemDataSource : DataExample.itemList.dataSource,
        itemTemplate: select('#listTemplate'),
        itemsDraggable : true,
        layout: { type : WinJS.UI.GridLayout }
    }">
</div>

Il prossimo esempio mostra come aggiungere una semplice funzionalità di trascinamento a un controllo ListView in fase di esecuzione tramite JavaScript.

(function () {

    // Other JavaScript code ...

    // Get a reference to the ListView control.
    var listView = 
        document.querySelector('#listView').winControl;

    // Set the controls itemsReorderable property.
    listView.itemsDraggable = true;

    // Other JavaScript code ...

})();

Dopo aver impostato la proprietà itemsDraggable su true, esegui l'app (premi F5). Nell'app seleziona un elemento dal controllo ListView e trascinalo al di fuori del controllo ListView. L'elemento viene visualizzato in ghosting sull'interfaccia dell'app all'esterno del controllo ListView. Quando rilasci il pulsante del mouse, l'elemento scompare. Vengono quindi attivati gli eventi di trascinamento appropriati.

Se vuoi interagire con l'origine dati sottostante di un controllo ListView, devi anche implementare i gestori per alcuni degli eventi di trascinamento della selezione del controllo ListView. Nell'esempio seguente è stato aggiunto un gestore all'evento ListView.itemdragstart e agli eventi dragover e drop di ItemContainer.

Per usare questo codice con l'esempio precedente, aggiungilo al gestore dell'evento app.onactivated definito nel file default.js incluso nel modello Blank app (js/default.js).

// Get the data from the ListView when the user drags an item.
listView.addEventListener("itemdragstart", function (evt) {

    // Store the index of the item from the data source of 
    // the ListView in the DataTransfer object of the event.
    evt.detail.dataTransfer.setData("Text",
        JSON.stringify(evt.detail.dragInfo.getIndices()));
});

// Allows the drop to occur. The default behavior disallows
// an element from being dropped upon another.
listViewDetailInfo.addEventListener('dragover', function (evt) {
    evt.preventDefault();
});

// Insert the content (from the ListView) into the ItemContainer.
listViewDetailInfo.addEventListener('drop', function (evt) {

    // Get the index of the selected item out of the event object.
    var dragIndex = JSON.parse(evt.dataTransfer.getData("Text")),
        dataSource = listView.winControl.itemDataSource;

    // Extract the selected data from the data source 
    // connected to the ListView control.
    dataSource.itemFromIndex(Number(dragIndex)).
        then(function (item) {
            if (item) {
                var itemData = item.data;

                // Update the ItemContainer with the data from
                // the item dragged from the ListView control.
                listViewDetailInfo.querySelector('h4').innerText = itemData.title;
                listViewDetailInfo.querySelector('h6').innerText = itemData.text;
                istViewDetailInfo.querySelector('span').innerText = itemData.description;
            }
        });

});

Nell'esempio precedente, i dati selezionati trascinati dal controllo ListView sono stati archiviati nell'oggetto DataTransfer associato all'evento itemdragstart. Dato che entrambi i gestori possono accedere alla stessa origine dati, viene archiviato solo l'indice dell'elemento selezionato. In caso contrario, potresti serializzare l'oggetto come stringa in formato JSON nell'oggetto DataTransfer .

Nel gestore per l'evento dragover per ItemContainer viene disattivato il comportamento predefinito che non consente il rilascio di un elemento su un altro. Nel gestore dell'evento drop per l'oggetto ItemContainer l'indice dell'elemento selezionato dall'origine dati viene estratto dall'oggetto DataTransfer e l'elemento viene quindi recuperato dall'origine dati del controllo ListView. Il codice HTML dell'oggetto ItemContainer viene infine aggiornato con i nuovi dati.

Nota   Se l'app riordina oppure trascina elementi tra i gruppi in un controllo ListView raggruppato, devi rimuovere gli elementi dall'origine dati e quindi reinserirli nel nuovo gruppo. Per ottenere questo risultato, non puoi usare moveAfter, moveBefore o moveToStart.

 

Passaggio 4: Aggiungere funzionalità di rilascio a un controllo ListView

Puoi aggiungere funzionalità di rilascio a un controllo ListView in modo simile a come è stata aggiunta la funzionalità di rilascio al controllo ItemContainer nell'esempio precedente.

Usa l'esempio di codice seguente per aggiungere la possibilità di rilasciare i dati dal controllo ItemContainer al controllo ListView.

Per usare questo codice con l'esempio precedente, aggiungilo al gestore dell'evento app.onactivated definito nel file default.js incluso nel modello Blank app (js/default.js).

// Drop content (from the ItemContainer) onto the ListView control.
listView.addEventListener("itemdragdrop", function (evt) {
    if (evt.detail.dataTransfer) {
        var dragData = JSON.parse(
            evt.detail.dataTransfer.getData("Text"));

        // It's a good idea to validate the data before 
        // attempting to insert it into the data source!
        if (dragData && dragData.title && dragData.text) {
            var dropIndex = evt.detail.insertAfterIndex;

            // Insert the new item into the data source.
            DataExample.itemList.splice(dropIndex, 0, {
                title: dragData.title,
                text: dragData.text,
                description: dragData.description
            });
        }
    }
});

// Allows the drop to occur. The default behavior disallows
// an element from being dropped upon another.
listView.addEventListener("itemdragenter", function (evt) {
    if (evt.detail.dataTransfer &&
        evt.detail.dataTransfer.types.contains("Text")) {
        evt.preventDefault();
    }
});

// Drag content from the ItemContainer.
listViewDetailInfo.addEventListener('dragstart', function (evt) {

    // Get the data displayed in the ItemContainer and
    // store it in an anonymous object.
    var target = evt.target,
        title = target.querySelector('h4').innerText,
        text = target.querySelector('h6').innerText,
        description = target.querySelector('span').innerText,
        dragData = {
            source: target.id,
            title: title,
            text: text,
            description: description
        };
    
    // Store the data in the DataTransfer object as a
    // JSON-formatted string.                
    evt.dataTransfer.setData("Text", 
        JSON.stringify(dragData));
});

Nell'esempio precedente, un gestore eventi viene aggiunto all'evento dragstart del controllo ItemContainer e agli eventi itemdragenter e itemdragdrop del controllo ListView. Il gestore per l'evento ItemContainer.dragstart estrae i dati dal controllo ItemContainer e li archivia nell'oggetto DataTransfer associato all'evento come stringa in formato JSON. Nel gestore dell'evento ListView.onitemdragenter il comportamento predefinito dell'evento viene disattivato per consentirle il rilascio di contenuto HTML nel controllo ListView. Infine, quando viene generato l'evento ListView.onitemdragdrop, i dati vengono estratti dall'oggetto DataTransfer e quindi inseriti nell'origine dati del controllo ListView.

Nota   Se l'utente tenta di riordinare un controllo ListView tramite la tastiera, l'oggetto DataTransfer passato come argomento all'evento itemdragdrop è indefinito. Nel gestore per l'evento itemdragdrop è necessario assicurarsi che l'oggetto DataTransfer esista prima di tentare la lettura dei dati in esso contenuti.

 

Osservazioni

Per altre informazioni su come usare i controlli ListView e abilitare il riordinamento, il trascinamento e il rilascio nei controlli ListView, vedi l'esempio delle funzionalità di trascinamento della selezione e riordinamento del controllo HTML ListView.

Esempio completo

Argomenti correlati

Esempio delle funzionalità di trascinamento della selezione e riordinamento del controllo HTML ListView

Controlli