So wird’s gemacht: Anzeigen von Elementen unterschiedlicher Größe (HTML)
[ Dieser Artikel richtet sich an Windows 8.x- und Windows Phone 8.x-Entwickler, die Windows-Runtime-Apps schreiben. Wenn Sie für Windows 10 entwickeln, finden Sie weitere Informationen unter neueste Dokumentation ]
Standardmäßig ordnet das ListView allen Elementen in der Liste die gleiche Größe zu. Wenn Sie ein Rasterlayout verwenden, können Sie dieses Verhalten ändern und Elemente mit unterschiedlicher Größe anzeigen, indem Sie festlegen, dass sich die Elemente mehrere Zellen erstrecken.
Wissenswertes
Technologien
Voraussetzungen
- Es wird davon ausgegangen, dass Sie ein einfaches ListView-Objekt erstellen und verwenden können. Eine Einführung in das ListView-Steuerelement finden Sie unter Schnellstart: Hinzufügen einer Listenansicht.
Anweisungen
Zellen und Größenanpassung in der "ListView"
Bevor wir uns mit dem Code befassen, sollten Sie verstehen, wie die ListView Größenanpassungen behandelt.
Standardmäßig ordnet die ListView allen enthaltenen Elementen eine Zelle gleicher Größe zu. Hier ist eine ListView, die Elemente enthält, die alle gleich groß sind.
Hier ist die gleiche ListView, in der eine einzelne Zelle hervorgehoben ist.
Die Größe der Zelle wird durch die Größe des ersten Elements in der ListView bestimmt. Wenn die ListView unterschiedliche große Elemente enthält, ordnet sie dennoch die Zellgröße basierend auf der Größe des ersten Elements zu. Wenn ein Element größer als die anderen ist, wird es beschnitten, sodass es die gleiche Größe hat wie die anderen ListView-Elemente.
Dieses Verhalten können Sie ändern, indem Sie die Aufteilung auf mehrere Zellen aktivieren. Ein Element kann sich dann über mehrere Zellen erstrecken. In diesem Beispiel ist die Aufteilung auf mehrere Zellen aktiviert, sodass das größere Element nicht eine, sondern fünf Zellen beansprucht.
Wenn Sie die Aufteilung auf mehrere Zellen aktivieren, können Sie auch explizit die Größe der Basiszelle angeben. Wir empfehlen, die Größe aller Elemente in der ListView auf ein Vielfaches der Größe der Basiszelle festzulegen. Im nächsten Beispiel wird das größere Element so geändert, dass es doppelt so hoch wie die Basiszelle, aber genauso breit ist.
Hier erfahren Sie, wie Sie eine ListView erstellen, die Elemente mit drei verschiedenen Größen enthält.
Schritt 1: Erstellen der Daten und der "ListView"
Als Erstes erstellen wir eine Datenquelle und eine ListView.
Definieren Sie in einer JavaScript-Datei eine Datenquelle für die ListView. In diesem Beispiel wird eine List aus einem Array von JSON-Objekten erstellt und öffentlich zugänglich gemacht, indem sie mit WinJS.Namespace.define durch einen Namespace mit dem Namen
DataExamples
verfügbar gemacht wird.Die Daten ähneln denen in den Beispielen aus anderen Themen, beispielsweise Schnellstart: Hinzufügen einer "ListView". Jedoch ist ein
type
-Feld hinzugekommen. Es hat drei mögliche Werte: "smallListIconTextItem", "mediumListIconTextItem" und "largeListIconTextItem". In späteren Schritten weisen wir mit diesem Feld eine CSS-Klasse zu, die die Größe der einzelnen Elemente bestimmt.(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 }); })();
(Wenn Sie beim Schreiben des Codes die in diesem Beispiel verwendeten Bilder verwenden möchten, können Sie das Beispiel für "ListView"-Elementvorlagen herunterladen.)
Erstellen Sie in Ihrer HTML-Datei ein ListView-Element, für das die Aufteilung auf mehrere Zellen verwendet wird. Legen Sie dessen itemDataSource-Eigenschaft auf die Datenquelle fest, die Sie im vorherigen Schritt erstellt haben.
<div id="myListView" data-win-control="WinJS.UI.ListView" data-win-options="{ itemDataSource: DataExamples.myCellSpanningData.dataSource, layout: { type: WinJS.UI.CellSpanningLayout } }" ></div>
Schritt 2: Definieren der Größe der Basiszelle und Aktivieren der Aufteilung auf mehrere Zellen
Nun müssen wir die Größe der Basiszelle definieren.
Um für das ListView-Element ein Layout mit Aufteilung auf mehrere Zellen zu verwenden, erstellen Sie ein CellSpanningLayout-Objekt, mit dem Sie die layout-Eigenschaft des ListView-Steuerelements festlegen. Um die Aufteilung auf mehrere Zellen zu aktivieren und die Größe der Basiszelle zu definieren, erstellen Sie eine groupInfo-Funktion, die diese Informationen bereitstellt. Legen Sie mit der Funktion die groupInfo-Eigenschaft des CellSpanningLayout-Objekts fest. Die von uns definierte groupInfo-Funktion muss ein Objekt mit folgenden Eigenschaften zurückgeben.
enableCellSpanning
Legen Sie die Eigenschaft auf true fest, um die Aufteilung auf mehrere Zellen zu aktivieren. Der Standardwert lautet false.cellWidth
Die Breite der Basiszelle.cellHeight
Die Höhe der Basiszelle.
In diesem Beispiel verwenden wir für die Basiszelle eine Größe von 310 × 80 Pixel.
So definieren Sie die Größe der Basiszelle und aktivieren die Aufteilung auf mehrere Zellen
Erstellen Sie in der JavaScript-Datei, in der Sie die Daten erstellt haben, eine groupInfo-Funktion, die die Aufteilung auf mehrere Zellen aktiviert und für die Basiszelle eine Größe von 310 × 80 Pixel definiert.
// Enable cell spanning and specify // the cellWidth and cellHeight for the items var groupInfo = function groupInfo() { return { enableCellSpanning: true, cellWidth: 310, cellHeight: 80 }; };
Ermöglichen Sie mit WinJS.Utilities.markSupportedForProcessing den Zugriff auf die Funktion 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);
(Steuerelemente aus der Windows-Bibliothek für JavaScript können aus Sicherheitsgründen standardmäßig nicht auf Funktionen und Ereignishandler zugreifen. Mit der WinJS.Utilities.markSupportedForProcessing-Funktion können Sie dieses Standardverhalten überschreiben. Dabei wird vorausgesetzt, dass der von Ihnen bereitgestellte HTML-Code wohlgeformt ist und von WinJS verarbeitet werden kann. Weitere Informationen finden Sie unter Programmieren einfacher Apps.
Durch Aufrufen von WinJS.Utilities.markSupportedForProcessing für die Funktion wird nicht der öffentliche Zugriff ermöglicht. Dies geschieht im nächsten Schritt.
Ermöglichen Sie den öffentlichen Zugriff auf die groupInfo-Funktion, indem Sie sie über einen Namespace verfügbar machen. In diesem Beispiel wird der in Schritt 1.1 erstellte
DataExamples
-Namespace aktualisiert.WinJS.Namespace.define("DataExamples", { groupInfo : groupInfo, myCellSpanningData: myCellSpanningData });
Aktualisieren Sie die ListView, um die groupInfo-Funktion zu verwenden.
<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>
Schritt 3: Definieren der Größe eines Elements, das sich über eine einzige Zelle erstreckt
Nachdem wir die die Größe der Basiszelle definiert haben, können wir die Größen der Elemente definieren. Beim Definieren der Daten im ersten Schritt haben wir ein type
-Feld aufgenommen, das Infos zur möglichen Größe des Elements enthält: klein, mittel oder groß. Diese Infos können wir verwenden, um Elementgrößen zuzuweisen. Am besten verwenden wir CSS-Klassen zum Zuweisen der Größen. Diese Methode eignet sich unabhängig davon, ob wir eine Vorlagenfunktion oder eine WinJS.Binding.Template verwenden.
Unsere Basiszelle ist 310 Pixel breit und 80 Pixel hoch. Die Gesamtgröße der einzelnen Elemente muss ein Vielfaches der Größe der Basiszelle sein. Die Größe der Basiszelle entspricht der Größe des Elements plus dem Abstand, Rand und Rahmen des Elements:
Mit der folgenden Formel können Sie die Größe der Basiszelle berechnen:
- Breite der Basiszelle = Breite des Elements + horizontaler Abstand des Elements + horizontaler Rand des Elements + Stärke des Rahmens des Elements
- Höhe der Basiszelle = Höhe des Elements + vertikaler Abstand des Elements + vertikaler Rand des Elements + Stärke des Rahmens des Elements
So definieren Sie die Größe eines Elements, das eine einzige Basiszelle belegt
Definieren wir die Größe des kleinsten Elements. Erstellen Sie in der CSS-Datei (Cascading Stylesheets) eine CSS-Klasse mit dem Namen "smallListIconTextItem".
.smallListIconTextItem { }
Das kleinste Element beansprucht nur eine Zelle. Legen wir die Größe des Elements auf 300px, die Höhe auf 70px und den Abstand auf 5px fest.
.smallListIconTextItem { width: 300px; height: 70px; padding: 5px; overflow: hidden; background-color: Pink; display: -ms-grid; }
Überprüfen wir diese Zahlen anhand unserer Formel, um sicherzustellen, dass sie der Größe der Basiszelle entsprechen.
Breite der Zelle = Breite des Elements + linker Abstand + rechter Abstand + Stärke des Rahmens + linker Rand + rechter Rand = 300 + 5px + 5px + 0 + 0 + 0 = 310
Höhe der Zelle = Höhe des Elements + oberer Abstand + unterer Abstand + Stärke des Rahmens + oberer Rand + unterer Rand = 70px + 5px + 5px + 0 + 0 + 0= 80
Die Zahlen entsprechen der Größe der Basiszelle, daher können wir mit dem nächsten Schritt fortfahren.
Schritt 4: Definieren der Größen von Elementen, die sich über mindestens zwei Zellen erstrecken
Wenn Sie die Größe eines Elements bestimmen, das sich über eine oder mehrere Zellen erstreckt, müssen Sie auch den win-container
-Rand zwischen den jeweiligen Zellen berücksichtigen. Wenn Sie beispielsweise ein Element verwenden, das sich horizontal über eine Zelle, vertikal aber über zwei Zellen erstreckt, schließt die Gesamtgröße des Elements den unteren win-container
-Rand der ersten Zelle und den oberen win-container
-Rand der zweiten Zelle ein. Dies wird im Folgenden veranschaulicht.
Mit der folgenden Formel berechnen Sie die Gesamtgröße eines Elements, das sich über mehrere Zellen erstreckt:
Gesamtbreite des Elements = number of cells * Breite der Basiszelle + (number of cells - 1) * (linker
win-container
-Rand + rechterwin-container
-Rand)Gesamthöhe des Elements = number of cells * Höhe der Basiszelle + (number of cells - 1) * (oberer
win-container
-Rand + untererwin-container
-Rand)
Tipp Der win-container
-Rand ist standardmäßig auf 5 Pixel festgelegt.
So definieren Sie die Größe eines Elements, das sich vertikal über zwei Zellen erstreckt
Bestimmen Sie mit unserer Formel die Gesamthöhe des Elements:
Gesamthöhe des Elements = number of cells * Höhe der Basiszelle + (number of cells - 1) * (oberer
win-container
-Rand + untererwin-container
-Rand) = 2 * 80 + (2-1) * (5 + 5) = 170Erstellen Sie die CSS-Formatvorlage, die die Größe des Elements angibt. In diesem Beispiel wird ein Element definiert, das eine Höhe von 160 Pixel und einen Abstand von 5 Pixel hat. Entsprechend beträgt die Gesamthöhe 160 + 5 + 5 = 170. Da sich das Element horizontal nur über eine Zelle erstreckt, legen Sie die gleiche Breite und den gleichen Abstand fest wie in der CSS-Klasse
smallListIconTextItem
, die wir in Schritt 3 erstellt haben..mediumListIconTextItem { width: 300px; height: 160px; padding: 5px; overflow: hidden; background-color: LightGreen; display: -ms-grid; }
So definieren Sie die Größe eines Elements, das sich vertikal über drei Zellen erstreckt
Bestimmen Sie mit unserer Formel die Gesamthöhe des Elements:
Gesamthöhe des Elements = number of cells * Höhe der Basiszelle + (number of cells - 1) * (oberer
win-container
-Rand + untererwin-container
-Rand) = 3 * 80 + (3-1) * (5 + 5) = 260Erstellen Sie die CSS-Formatvorlage, die die Größe des Elements angibt. In diesem Beispiel wird ein Element definiert, das eine Höhe von 250 Pixel und einen Abstand von 5 Pixel hat. Entsprechend beträgt die Gesamthöhe 250 + 5 + 5 = 260.
.largeListIconTextItem { width: 300px; height: 250px; padding: 5px; overflow: hidden; background-color: LightBlue; display: -ms-grid; }
Schritt 5: Erstellen der Größenanpassungsfunktion für das CellSpanningLayout-Element
Zusätzlich zur groupInfo-Funktion muss vom CellSpanningLayout eine itemInfo-Funktion verfügbar gemacht werden, mit der bestimmt wird, welche Größe für Elemente unterschiedlicher Art in der Datenquelle festgelegt wird. Die itemInfo-Funktion muss ein JavaScript-Objekt mit den folgenden Eigenschaften zurückgeben:
So definieren Sie die Größe einzelner Elemente im ListView-Element
Erstellen Sie in der JavaScript-Datei, in der Sie Ihre Daten erstellt haben, eine itemInfo-Funktion, mit der ein Element aus der Datenquelle abgerufen und die entsprechende Größe und Höhe für das Element zurückgegeben wird.
// 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; });
Das itemInfo-Element ist von einem Aufruf von WinJS.Utilities.markSupportedForProcessing umschlossen, damit im HTML-Code auf die Funktion zugegriffen werden kann.
Ermöglichen Sie den öffentlichen Zugriff auf die itemInfo-Funktion, indem Sie sie über einen Namespace verfügbar machen. In diesem Beispiel wird der in Schritt 1.1 erstellte
DataExamples
-Namespace aktualisiert.WinJS.Namespace.define("DataExamples", { myCellSpanningData: myCellSpanningData, groupInfo: groupInfo, itemInfo: itemInfo });
Aktualisieren Sie die ListView, um die itemInfo-Funktion zu verwenden.
<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>
Schritt 6: Erstellen der Vorlage
Im letzten Schritt erstellen Sie eine Vorlage oder eine Vorlagenfunktion, in der die gerade definierten CSS-Klassen verwendet werden. Wir zeigen Ihnen, wie Sie eine WinJS.Binding.Template und eine Vorlagenfunktion erstellen.
Option A: Verwenden einer "WinJS.Binding.Template"
Definieren Sie in Ihrem HTML-Code eine 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>
Erinnern Sie sich, dass wir beim Definieren der Daten in Schritt 1.1 eine
type
-Eigenschaft aufgenommen haben, mit der angegeben wurde, welche CSS-Klasse den einzelnen Elementen zugewiesen wird? Jetzt können wir diese Daten verwenden. Binden Sie im Stammelement des Elements den Klassennamen an den Wert destype
-Felds der Daten.<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>
Hinweis Im Beispiel wird die Bindung an className, nicht an class ausgeführt. Der Grund ist, dass die zugrunde liegende JavaScript-Eigenschaft den Namen "className" hat, obwohl Sie "class" in HTML verwenden. Wenn die App das data-win-bind-Attribut verarbeitet, weist sie die gebundenen Werte über JavaScript-Aufrufe zu.
Das heißt, wenn der HTML-Attributname und der zugrunde liegende JavaScript-Eigenschaftenname unterschiedlich sind, verwenden Sie beim Festlegen von data-win-bind den JavaScript-Eigenschaftennamen.
Aktualisieren Sie die ListView so, dass sie die Vorlage verwendet, indem Sie ihre itemTemplate-Eigenschaft auf die ID der Vorlage festlegen.
<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
Wenn Sie möchten, können Sie anstelle einer WinJS.Binding.Template eine Vorlagenfunktion verwenden. Wenn Sie eine Vorlagenfunktion verwenden, haben Sie mehr Flexibilität beim Generieren des HTML-Codes und beim Zuweisen von Größen.
Option B: Verwenden einer Vorlagenfunktion
Definieren Sie die Vorlagenfunktion in einer JavaScript-Datei. Sie können diesen Code der gleichen Datei hinzufügen, die Ihre Daten enthält, oder den Code einer anderen Datei hinzufügen. Stellen Sie nur sicher, dass die Seite mit der ListView auf diese Datei verweist.
In diesem Beispiel werden die
type
-Daten für jedes Element verwendet, um die CSS-Klasse zuzuweisen, die die jeweilige Größe bestimmt.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; }); };
Rufen Sie markSupportedForProcessing für die Funktion auf, um den Zugriff über Markup zu ermöglichen.
WinJS.Utilities.markSupportedForProcessing(myCellSpanningJSTemplate);
Ermöglichen Sie mit WinJS.Namespace.define den öffentlichen Zugriff auf die Funktion.
WinJS.Namespace.define("Templates", { myCellSpanningJSTemplate: myCellSpanningJSTemplate });
Aktualisieren Sie in Ihrem HTML-Code die ListView so, dass die Vorlagenfunktion verwendet wird, indem Sie die itemTemplate-Eigenschaft auf den Namen der Vorlagenfunktion festlegen.
<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>
Unabhängig von der für die Vorlage verwendeten Methode zeigt die ListView unterschiedlich große Elemente an, wenn Sie die App ausführen.
Anmerkungen
Bearbeiten von Elementen
Wenn Sie Elemente in einer ListView ändern, für die die Aufteilung auf mehrere Zellen aktiviert ist, rufen Sie bei jeder Änderung ListView.recalculateItemPosition auf.
- Wenn die Datenquelle eine WinJS.Binding.List ist, rufen Sie recalculateItemPosition sofort nach dem Bearbeiten auf (beispielsweise nach dem Aufrufen von List.push oder List.splice).
- Wenn es sich bei der Datenquelle um eine benutzerdefinierte VirtualizedDataSource handelt, rufen Sie beginEdits auf, und nehmen Sie die Bearbeitungen vor. Rufen Sie dann recalculateItemPosition gefolgt von endEdits auf.