Comment activer les fonctionnalités de réorganisation, de glissement et de déplacement d’éléments dans un contrôle ListView

[ Cet article est destiné aux développeurs Windows 8.x et Windows Phone 8.x qui créent des applications Windows Runtime. Si vous développez une application pour Windows 10, voir la Documentation ]

Découvrez comment ajouter des fonctionnalités de réorganisation, de glissement et de déplacement d’éléments dans un contrôle ListView. (Windows uniquement)

Ce que vous devez savoir

Technologies

Prérequis

  • Vous devez être en mesure de créer une application du Windows Store de base en JavaScript qui utilise des contrôles WinJS. Pour obtenir des instructions sur l’utilisation des contrôles WinJS, voir Démarrage rapide : ajout de contrôles et de styles WinJS.

  • Pour ajouter des fonctionnalités complémentaires, vous devez savoir comment créer un contrôle ListView de base. Pour obtenir une vue d’ensemble sur la manière de créer un contrôle ListView simple, consultez Démarrage rapide : ajout d’un contrôle ListView ou la documentation de référence relative au contrôle ListView.

Instructions

Étape 1: Configurer l’exemple

Cet exemple montre comment créer un contrôle ListView et un objet ItemContainer pour afficher des informations sur un élément de la liste.

Utilisez le balisage HTML suivant comme code de base pour le contrôle ListView. Vous pouvez copier et coller le code dans le fichier default.html au sein d’un modèle Application vide dans 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’exemple utilise également le style CSS pour ajuster le contrôle ListView et l’objet ItemContainer sur la page HTML. Ajoutez le code CSS suivant dans la feuille de style qui est associée au contrôle ListView (css/default.css dans le modèle Application vide).


/* 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’exemple remplit le contrôle ListView avec certaines données prédéfinies. Ces données se trouvent dans un fichier « data.js » situé dans le dossier js (js/data.js). Suivez les instructions ci-dessous pour ajouter les données ListView dans l’application.

Dn423315.wedge(fr-fr,WIN.10).gifPour ajouter un fichier de données JavaScript dans votre application

  1. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le dossier js, puis sélectionnez Ajouter > Nouveau fichier JavaScript.

  2. Dans la boîte de dialogue Ajouter un nouvel élément, dans la zone Nom, tapez « data.js », puis cliquez sur Ajouter.

  3. Dans l’Explorateur de solutions, double-cliquez sur le nouveau fichier JavaScript et ajoutez le code suivant.

    (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
        });
    
    })();
    

Remarque  Vous pouvez remplacer les données prédéfinies par d’autres données de votre choix. Pour remplacer la source de données, vous pouvez changer le jeu de données qui est passé à la méthode constructeur WinJS.Binding.List.

Si vous préférez utiliser une source de données autre qu’un objet IListDataSource, celle-ci doit implémenter les méthodes moveBefore, moveAfter et moveToStart. En pratique, il est recommandé d’utiliser l’objet List fourni par WinJS pour inclure votre source de données.

Notez aussi que l’objet Template, défini dans le balisage HTML de l’application, utilise une source de données qui contient des éléments ayant les propriétés title et text. Si vos données ne comportent pas les propriétés title ou text, vous devez modifier la définition de l’objet Template.

 

Étape 2: Ajouter la fonctionnalité de réorganisation au contrôle ListView

Vous pouvez très facilement ajouter une fonctionnalité de réorganisation à un contrôle ListView. Pour cela, vous avez simplement à modifier ou compléter légèrement le code existant. En fait, il vous suffit de définir la propriété itemsReorderable du contrôle ListView à la valeur « true » (la valeur par défaut étant « false »).

Vous pouvez définir cette fonctionnalité de façon déclarative dans le balisage HTML du contrôle ou bien l’ajouter au moment de l’exécution à l’aide de JavaScript. L’exemple suivant montre comment ajouter la fonctionnalité de réorganisation en modifiant le balisage HTML du contrôle.

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

Le deuxième exemple indique comment ajouter cette fonctionnalité à un contrôle ListView au moment de l’exécution à l’aide de 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 ...

})();

Après avoir modifié la propriété itemsReorderable du contrôle ListView, exécutez le projet en appuyant sur F5. Sélectionnez un élément du contrôle ListViewet faites-le glisser vers un autre emplacement dans le même contrôle ListView.

Étape 3: Ajouter une fonctionnalité de glissement à un contrôle ListView

À un niveau de base, vous pouvez ajouter une fonctionnalité de glissement à un contrôle ListView aussi simplement qu’une fonctionnalité de réorganisation. Le contrôle ListView contient une propriété itemsDraggable que vous pouvez soit définir de façon déclarative dans le balisage HTML du contrôle, soit modifier au moment de l’exécution.

L’exemple suivant montre comment ajouter une fonctionnalité de glissement simple à un contrôle ListView dans son balisage HTML.

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

Le deuxième exemple décrit comment ajouter cette même fonctionnalité à un contrôle ListView au moment de l’exécution à l’aide de 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 ...

})();

Après avoir défini la propriété itemsDraggable avec la valeur true, exécutez l’application en appuyant sur F5. Dans l’application, sélectionnez un élément du contrôle ListView et faites-le glisser en dehors de ListView. L’élément est dupliqué sur l’interface de l’application en dehors de ListView. Quand vous relâchez le bouton de la souris, l’élément disparaît. Les événements de déplacement appropriés sont ensuite déclenchés.

Pour pouvoir interagir avec la source de données sous-jacente d’un contrôle ListView, vous devez également implémenter des gestionnaires pour certains événements de glisser-déplacer de ListView. Dans l’exemple suivant, un gestionnaire a été ajouté à l’événement ListView.itemdragstart, ainsi qu’aux événements dragover et drop de l’objet ItemContainer.

Pour utiliser ce code avec l’exemple précédent, ajoutez-le dans le gestionnaire d’événements app.onactivated qui est défini dans le fichier default.js fourni avec le modèle 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;
            }
        });

});

Dans l’exemple précédent, les données sélectionnées qui ont été déplacées en dehors de ListView ont été enregistrées dans l’objet DataTransfer associé à l’événement itemdragstart. Les deux gestionnaires ayant la possibilité d’accéder à la même source de données, seul l’index de l’élément sélectionné est enregistré. Sinon, vous pourriez sérialiser l’objet en tant que chaîne au format JSON dans l’objet DataTransfer.

Dans le gestionnaire d’événements dragover de l’objet ItemContainer, le comportement par défaut est supprimé (par défaut, le positionnement d’un élément au-dessus d’un autre n’est pas autorisé). Dans le gestionnaire d’événements drop de l’objet ItemContainer, l’index de l’élément sélectionné dans la source de données est extrait de l’objet DataTransfer, puis l’élément est récupéré à partir de la source de données de ListView. Pour finir, le balisage HTML de l’objet ItemContainer est mis à jour avec les nouvelles données.

Remarque   Si votre application peut réorganiser et faire glisser-déplacer des éléments entre différents groupes d’un contrôle ListView regroupé, vous devez supprimer les éléments dans la source de données, puis les ajouter dans le nouveau groupe. Pour faire cela, vous ne pouvez pas utiliser les méthodes moveAfter, moveBefore et moveToStart.

 

Étape 4: Ajouter une fonctionnalité de déplacement à un contrôle ListView

Vous pouvez ajouter une fonctionnalité de déplacement à un contrôle ListView de la même manière que vous avez ajouté la fonctionnalité de glissement au contrôle ItemContainer dans l’exemple précédent.

Utilisez l’exemple de code suivant pour ajouter une fonctionnalité permettant de déplacer des données du contrôle ItemContainer vers ListView.

Pour utiliser ce code avec l’exemple précédent, ajoutez-le dans le gestionnaire d’événements app.onactivated qui est défini dans le fichier default.js fourni avec le modèle 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));
});

Dans l’exemple de code précédent, un gestionnaire a été ajouté à l’événement dragstart du contrôle ItemContainer ainsi qu’aux événements itemdragenter et itemdragdrop du contrôle ListView. Le gestionnaire de l’événement ItemContainer.dragstart extrait les données de l’objet ItemContainer, puis il les enregistre dans l’objet DataTransfer associé à l’événement en tant que chaîne au format JSON. Dans le gestionnaire d’événements ListView.onitemdragenter, le comportement par défaut de l’événement a été supprimé pour autoriser le déplacement du contenu HTML vers le contrôle ListView. Pour finir, quand l’événement ListView.onitemdragdrop est déclenché, les données sont extraites de l’objet DataTransfer, puis elles sont ajoutées dans la source de données du contrôle ListView.

Remarque   Si l’utilisateur essaie de réorganiser un contrôle ListView à l’aide du clavier, l’objet DataTransfer qui est passé en tant qu’argument à l’événement itemdragdrop n’est pas défini. Dans le gestionnaire d’événements itemdragdrop, vous devez vérifier que l’objet DataTransfer existe bien avant d’essayer de lire les données qu’il contient.

 

Remarques

Pour plus d’informations sur l’utilisation des contrôles ListView et sur l’activation des fonctionnalités de réorganisation et de glisser-déplacer au sein des contrôles ListView, voir l’exemple ListView HTML pour le glisser-déplacer et la réorganisation.

Terminer l’exemple

Rubriques associées

Exemple ListView HTML pour le glisser-déplacer et la réorganisation

Contrôles