Comment afficher des éléments de tailles différentes (HTML)
[ 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 ]
Par défaut, le contrôle ListView alloue la même taille à chaque élément dans la liste. Lorsque vous utilisez une disposition de grille, vous pouvez modifier ce comportement et afficher des éléments de tailles différentes en permettant aux éléments de recouvrir plusieurs cellules.
Ce que vous devez savoir
Technologies
Prérequis
- Nous partons du principe que vous savez créer et utiliser un objet ListView de base. Pour obtenir une présentation du contrôle ListView, voir Démarrage rapide : ajout d’un contrôle ListView.
Instructions
À propos des cellules et dimensionnement dans le contrôle ListView
Avant d’examiner le code, il est intéressant de comprendre la façon dont le contrôle ListView gère le dimensionnement des éléments.
Par défaut, le contrôle ListView alloue la même taille de cellule pour chaque élément qu’il contient. Voici un contrôle ListView qui contient des éléments présentant tous la même taille.
Voici le même contrôle ListView, avec une cellule individuelle affichée en surbrillance.
La taille du cellule est déterminée par la taille du premier élément dans le contrôle ListView. Lorsque le contrôle ListView contient des éléments de différentes tailles, il alloue toujours la taille de cellule sur base de la taille du premier élément. Par conséquent, si un élément est plus grand que les autres, il sera tronqué pour correspondre à la taille des autres éléments ListView.
Vous pouvez modifier ce comportement en activant le fractionnement des cellules. Lorsque vous procédez ainsi, un élément peut occuper plusieurs cellules. Dans cet exemple, le fractionnement des cellules est activé, de sorte que l’élément le plus grand occupe 5 cellules au lieu d’une.
Une fois le fractionnement des cellules activé, vous pouvez également préciser de manière explicite la taille de la cellule de base. Pour chaque élément de votre contrôle ListView, nous vous recommandons de définir une taille qui équivaut à un multiple de la taille de cellule de base. Dans l’exemple suivant, l’élément le plus grand est modifié de façon à avoir deux fois la hauteur de la cellule de base et à avoir la même largeur.
Voici comment créer un contrôle ListView qui contient des éléments de trois tailles différentes.
Étape 1 : créer vos données et le contrôle ListView
Tout d’abord, créez une source de données et un contrôle ListView.
Dans un fichier JavaScript, définissez une source de données pour le contrôle ListView. Cet exemple crée un contrôle List à partir d’un tableau d’objets JSON et le rend publiquement accessible en utilisant WinJS.Namespace.define pour l’exposer par le biais d’un espace de noms intitulé
DataExamples
.Les données sont semblables aux exemples fournis dans d’autres rubriques, telles que Démarrage rapide : ajout d’un contrôle ListView, avec un ajout : un champ
type
. Trois valeurs sont possibles : "smallListIconTextItem", "mediumListIconTextItem" et "largeListIconTextItem". Par la suite, nous utilisons ce champ pour affecter une classe CSS qui détermine la taille de chaque élément.(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 }); })();
(Si vous codez en même temps et que vous voulez utiliser les images figurant dans cet exemple, vous pouvez les obtenir en téléchargeant l’ Exemple de modèles d’éléments du contrôle ListView.)
Dans votre fichier HTML, créez un contrôle ListView qui utilise la disposition de fractionnement des cellules. Définissez sa propriété itemDataSource sur la source de données créée à l’étape précédente.
<div id="myListView" data-win-control="WinJS.UI.ListView" data-win-options="{ itemDataSource: DataExamples.myCellSpanningData.dataSource, layout: { type: WinJS.UI.CellSpanningLayout } }" ></div>
Étape 2 : définir la taille de la cellule de base et activer le fractionnement des cellules
À présent, nous devons définir la taille de la cellule de base.
Pour que le contrôle ListView utilise une disposition de fractionnement des cellules, vous devez créer un objet CellSpanningLayout et vous en servir pour définir la propriété layout du contrôle ListView. Pour activer le fractionnement des cellules et définir la taille de la cellule de base, vous devez créer une fonction groupInfo fournissant ces informations et l’utiliser pour définir la propriété groupInfo de l’objet CellSpanningLayout. La fonction groupInfo que nous définissons doit retourner un objet qui contient ces propriétés.
enableCellSpanning
Définissez cette propriété sur true pour activer le fractionnement des cellules. La valeur par défaut est false.cellWidth
La largeur de la cellule de base.cellHeight
La hauteur de la cellule de base.
Dans le cadre de cet exemple, utilisons une taille de cellule de base de 310×80 pixels.
Pour définir la taille de la cellule de base et activer le fractionnement des cellules
Dans le fichier JavaScript où vous avez créé vos données, créez une fonction groupInfo qui active le fractionnement des cellules et définit la cellule de base sur une taille de 310×80 pixels.
// Enable cell spanning and specify // the cellWidth and cellHeight for the items var groupInfo = function groupInfo() { return { enableCellSpanning: true, cellWidth: 310, cellHeight: 80 }; };
Utilisez WinJS.Utilities.markSupportedForProcessing pour rendre votre fonction accessible en mode 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);
(Par défaut, les fonctions et gestionnaires d’événements ne sont pas accessibles aux contrôles de la Bibliothèque Windows pour JavaScript pour des raisons de sécurité. La fonction WinJS.Utilities.markSupportedForProcessing vous permet d’ignorer ce comportement par défaut. Elle part du principe que les données HTML que vous fournissez sont correctement mises en forme et peuvent être traitées par WinJS. Pour plus d’informations, voir Codage d’applications de base.)
L’appel de WinJS.Utilities.markSupportedForProcessing dans votre fonction ne la rend pas accessible publiquement. Cette opération fait l’objet de l’étape suivante.
Rendez votre fonction groupInfo accessible publiquement en l’exposant via un espace de noms. Cet exemple met à jour l’espace de noms
DataExamples
que nous avons créé à l’étape 1.1.WinJS.Namespace.define("DataExamples", { groupInfo : groupInfo, myCellSpanningData: myCellSpanningData });
Mettez à jour votre contrôle ListView afin d’utiliser la fonction 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>
Étape 3 : définir la taille d’un élément figurant dans une cellule unique
Maintenant que nous avons défini la taille de notre cellule de base, nous pouvons définir la taille de nos éléments. Lorsque nous avons défini nos données lors de la première étape, nous avons inclus un champ type
contenant des informations sur la taille possible de l’élément : petite, moyenne ou grande. Nous pouvons utiliser ces informations pour affecter des tailles d’éléments. La meilleure façon d’affecter les tailles consiste à utiliser les classes CSS. Cette méthode fonctionne, que nous utilisions une fonction de modélisation ou un modèle WinJS.Binding.Template.
Notre cellule de base fait 310 pixels en largeur sur 80 pixels en hauteur. La taille totale de chaque élément doit être un multiple de la taille de la cellule de base. La taille de la cellule de base correspond à la taille de l’élément, plus le remplissage, la marge et la bordure de l’élément :
Voici la formule permettant de calculer la taille de la cellule de base :
- largeur cellule base = largeur élément + remplissage horizontal élément + marge horizontale élément + épaisseur bordure élément
- hauteur cellule base = hauteur élément + remplissage vertical élément + marge verticale élément + épaisseur bordure élément
Pour définir la taille d’un élément occupant une cellule de base unique
Définissons la taille du plus petit élément. Dans votre fichier CSS, créez une classe CSS (feuilles de style en cascade) intitulée "smallListIconTextItem".
.smallListIconTextItem { }
Le plus petit élément occupe une seule cellule. Définissons la largeur de l’élément sur 300px, sa hauteur sur 70px et son remplissage sur 5px.
.smallListIconTextItem { width: 300px; height: 70px; padding: 5px; overflow: hidden; background-color: Pink; display: -ms-grid; }
Vérifions ces nombres sur base de notre formule pour nous assurer qu’ils correspondent à notre taille de cellule de base.
largeur cellule = largeur élément + remplissage gauche + remplissage droit + épaisseur bordure + marge gauche + marge droite = 300 + 5px + 5px + 0 + 0 + 0 = 310
hauteur cellule = hauteur élément + remplissage haut + remplissage bas + épaisseur bordure + marge supérieure + marge inférieure = 70px + 5px + 5px + 0 + 0 + 0 = 80
Cela correspond à notre taille de cellule de base. Passons à l’étape suivante.
Étape 4 : définir la taille d’éléments recouvrant 2 cellules ou plus
Lorsque vous déterminez la taille d’un élément couvrant une ou plusieurs cellules, vous devez également prendre en compte la marge win-container
entre les cellules recouvertes par l’élément. Par exemple, si vous avez un élément recouvrant une cellule horizontalement mais deux cellules verticalement, sa taille d’élément totale inclut la marge inférieure win-container
de la première cellule et la marge supérieure win-container
de la deuxième cellule, comme illustré ci-dessous.
Voici la formule permettant de calculer la taille totale d’un élément recouvrant plusieurs cellules :
largeur élément totale = number of cells * largeur cellule base + (number of cells - 1) * (
win-container
marge gauche +win-container
marge droite)largeur élément totale = number of cells * hauteur cellule base + (number of cells - 1) * (
win-container
marge supérieure +win-container
marge inférieure)
Astuce La marge par défaut win-container
est de 5 pixels.
Pour définir la taille d’un élément recouvrant verticalement deux cellules
Utilisez notre formule pour déterminer la hauteur d’élément totale :
hauteur élément totale = number of cells * hauteur cellule base + (number of cells - 1) * (
win-container
marge supérieure +win-container
marge inférieure) = 2 * 80 + (2-1) * (5 + 5) = 170Créez le style CSS qui spécifie l’élément de taille. Cet exemple définit un élément avec une hauteur de 160 pixels et un remplissage de 5 pixels, soit une hauteur totale de 160 + 5 + 5 = 170. Étant donné que l’élément recouvre une seule cellule horizontalement, attribuez-lui la même largeur et le même remplissage que la classe CSS créée à l’étape 3,
smallListIconTextItem
..mediumListIconTextItem { width: 300px; height: 160px; padding: 5px; overflow: hidden; background-color: LightGreen; display: -ms-grid; }
Pour définir la taille d’un élément recouvrant verticalement trois cellules
Utilisez notre formule pour déterminer la hauteur d’élément totale :
hauteur élément totale = number of cells * hauteur cellule base + (number of cells - 1) * (
win-container
marge supérieure +win-container
marge inférieure) = 3 * 80 + (3-1) * (5 + 5) = 260Créez le style CSS qui spécifie l’élément de taille. Cet exemple définit un élément avec une hauteur de 250 pixels et un remplissage de 5 pixels, soit une hauteur totale de 250 + 5 + 5 = 260.
.largeListIconTextItem { width: 300px; height: 250px; padding: 5px; overflow: hidden; background-color: LightBlue; display: -ms-grid; }
Étape 5 : créer la fonction de dimensionnement des éléments pour CellSpanningLayout
En plus de la fonction groupInfo, l’objet CellSpanningLayout doit dévoiler une fonction itemInfo qui détermine la manière de dimensionner des éléments de types différents dans la source de données. La fonction itemInfo doit retourner un objet JavaScript contenant les propriétés suivantes :
width
La largeur de l’élément individuel dans le contrôle ListView.height
La hauteur de l’élément individuel dans le contrôle ListView.
Pour définir la taille des éléments individuels dans le contrôle ListView
Dans le fichier JavaScript où vous avez créé vos données, créez une fonction itemInfo qui extrait un élément de la source de données et retourne la taille et la hauteur correspondant à cet élément.
// 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; });
La propriété itemInfo est encapsulée par un appel à WinJS.Utilities.markSupportedForProcessing pour rendre la fonction accessible dans HTML.
Rendez votre fonction itemInfo accessible publiquement en l’exposant par le biais d’un espace de noms. Cet exemple met à jour l’espace de noms
DataExamples
que nous avons créé à l’étape 1.1.WinJS.Namespace.define("DataExamples", { myCellSpanningData: myCellSpanningData, groupInfo: groupInfo, itemInfo: itemInfo });
Mettez à jour votre contrôle ListView afin d’utiliser la fonction 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>
Étape 6 : créer le modèle
La dernière étape consiste à créer un modèle ou une fonction de modélisation qui utilise les classes CSS que nous venons de définir. Nous allons vous montrer comment créer à la fois un modèle WinJS.Binding.Template et une fonction de modélisation.
Option A : utiliser un modèle WinJS.Binding.Template
Dans votre code HTML, définissez un modèle 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>
Vous souvenez-vous de la manière dont, lors de l’étape 1.1, nous avons inclus une propriété
type
qui spécifiait la classe CSS affectée à chaque élément ? Nous pouvons à présent utiliser ces données. Dans l’élément racine de l’élément, liez le nom de classe à la valeur du champtype
de nos données.<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>
Remarque L’exemple est lié à className, et non à class. La raison en est que, même si vous utilisez "class" en HTML, la propriété JavaScript de stockage est intitulée "className". Lorsque votre application traite l’attribut data-win-bind, elle affecte les valeurs liées par le biais d’appels JavaScript.
Cela signifie que chaque fois que le nom d’attribut HTML et le nom de propriété JavaScript de stockage sont différents, vous utilisez le nom de propriété JavaScript lorsque vous définissez data-win-bind.
Mettez à jour votre contrôle ListView pour utiliser le modèle en définissant sa propriété itemTemplate sur l’ID de votre modèle.
<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
Si vous le souhaitez, vous pouvez utiliser une fonction de modélisation au d’un modèle WinJS.Binding.Template. L’utilisation d’une fonction de modélisation peut vous procurer plus de souplesse lors de la génération de votre code HTML et de l’affectation de tailles.
Option B : utiliser une fonction de modélisation
Dans un fichier JavaScript, définissez votre fonction de modélisation. Vous pouvez ajouter ce code au même fichier que celui qui contient vos données ou vous pouvez l’ajouter à un autre fichier. Veillez juste à ce que la page contenant votre contrôle ListView fasse référence à ce fichier.
Cet exemple utilise les données
type
pour chaque élément afin de lui affecter la classe CSS déterminant sa taille.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; }); };
Appelez markSupportedForProcessing dans la fonction de façon à ce qu’il soit accessible par le biais du balisage.
WinJS.Utilities.markSupportedForProcessing(myCellSpanningJSTemplate);
Utilisez WinJS.Namespace.define pour rendre la fonction publiquement accessible.
WinJS.Namespace.define("Templates", { myCellSpanningJSTemplate: myCellSpanningJSTemplate });
Dans votre code HTML, mettez à jour votre contrôle ListView pour utiliser la fonction de modélisation en définissant sa propriété itemTemplate sur le nom de votre fonction de modélisation.
<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>
Quelle que soit la méthode de modélisation que vous avez choisie, lorsque vous exécutez l’application, le contrôle ListView affiche des éléments de tailles multiples.
Remarques
Modification d’éléments
Lorsque vous modifiez des éléments dans un contrôle ListView pour lequel le fractionnement des cellules est activé, appelez ListView.recalculateItemPosition chaque fois que vous effectuez une modification.
- Si la source de données est une liste WinJS.Binding.List, appelez recalculateItemPosition immédiatement après avoir effectué une modification (par exemple, après l’appel de List.push ou List.splice).
- Si la source de données est une source VirtualizedDataSource personnalisée, appelez beginEdits, effectuez vos modifications, appelez recalculateItemPosition, puis appelez endEdits.