Moderne Apps

Alles Wissenswerte zum WinJS-ListView-Steuerelement

Rachel Appel

Rachel AppelSie verwalten Daten. Viele Daten. Sie müssen diese Daten so präsentieren, dass Benutzer in Ihrer App ohne Probleme auf die Daten zugreifen können und sie zudem verstehen. Daten werden in Apps unterschiedlich verfügbar gemacht: in Form von Nachrichtenartikeln, Rezepten, Sportergebnissen, Finanzdiagrammen usw. Alle wandern in Abteilungen unterschiedlicher Größe über den Bildschirm und versuchen, die Aufmerksamkeit des Verbrauchers auf sich zu ziehen. Sinnvollerweise werden Daten von den meisten heute erhältlichen Apps in einem Raster- oder Listenformat präsentiert, da Benutzer kleine bis mittelgroße Datenraster mühelos verwenden, durchsuchen und filtern können. Von Unternehmens-Apps bis hin zu persönlichen und anderen Apps bieten Raster das Gerüst, mit dem Daten für eine schnelle Durchsicht bereitgestellt werden können.

In Windows Store-Apps können Sie das ListView-Steuerelement verwenden, um die Struktur für eine Datenpräsentation einzurichten. Wenn Sie mit der Windows Store-Apps-Entwicklung noch nicht vertraut sind, können Sie sich mithilfe meines Artikels vom Februar 2013 schnell in das Thema einarbeiten: „Erstellen von Windows Store-Apps mit HTML5 und JavaScript“ (msdn.microsoft.com/magazine/jj891058). Alternativ können Sie sich in meinem Artikel vom Juli 2013 einen Überblick verschaffen: „Verwenden von Steuerelementen und Einstellungen in Windows Store-Apps, die mit JavaScript erstellt wurden“ (msdn.microsoft.com/magazine/dn296546).

Grundlagen zum ListView-Steuerelement

„ListView“ steht als HTML und XAML zur Verfügung und ist heute das Steuerelement der Wahl zum Darstellen von Daten in einem Raster- oder Listenformat. In Windows-Bibliothek für JavaScript(WinJS)-Apps (die in diesem Artikel im Mittelpunkt stehen) können Sie das ListView-Steuerelement verwenden, indem Sie das Attribut „data-win-control“ in einem Host-<div>-Element auf „WinJS.UI.ListView“ setzen, etwa folgendermaßen:

    <div id="listView" data-win-control= "WinJS.UI.ListView"></div>

Das <div>-Element, das „ListView“ hostet, enthält keine untergeordneten Elemente. In ihm sind jedoch grundlegende Konfigurationsinformationen enthalten, und zwar in einem Attribut mit dem Namen „data-win-options“. Mit „Data-win-options“ können Sie mithilfe deklarativer Syntax in der HTML-Seite eine beliebige Eigenschaft des ListView-Steuerelements festlegen. Wenden Sie folgende Merkmale an, um „ListView“ ordnungsgemäß zu verwenden:

  • Die Gruppen- und Item-Vorlagen für „ListView“
  • Die Gruppen- und Elementdatenquellen von „ListView“
  • Bestimmung, ob „ListView“ ein Raster- oder Listenlayout verwendet (standardmäßig ein Raster)

Geben Sie auch an, ob „ListView“ einen einfachen oder mehrfachen Elementauswahlmodus verwendet (standardmäßig mehrfach). Ein grundlegendes ListView-Element mit den im data-win-options-Attribut festgelegten layout- und selectionMode-Eigenschaften sieht folgendermaßen aus:

    <div id="listView" data-win-control= "WinJS.UI.ListView" data-win-options=
      "{ selectionMode: 'single', layout : {type: WinJS.UI.GridLayout} }" ></div>

Auch wenn im vorangestellten Code „ListView“ definiert wird, funktioniert „ListView“ nicht eigenständig. Benötigt wird die Unterstützung des WinJS.Binding.List-Objekts. Das List-Objekt bindet Arrays, die mit Objekten gefüllt sind, an die in den Item- und Group-Vorlagen definierten HTML-Elemente. Das bedeutet, dass das List-Objekt definiert, welche Daten angezeigt werden, während die Vorlage definiert, wie diese Daten angezeigt werden.

Erstellen von ListView-Vorlagen

Sobald Sie das <div>-Element für „ListView“ eingerichtet haben, können Sie Vorlagen dafür erstellen. „ListView“ ist von den HTML-Vorlagen abhängig, um Daten anzuzeigen, die für die Benutzer lesbar sind. Glücklicherweise enthalten die Windows Store-Vorlagen für Raster-Apps, geteilte Apps und Hub-Apps (die Hub-App ist in Windows 8.1 verfügbar) alles, was für das Darstellen von Daten in einem Raster- oder Listenformat erforderlich ist. Dazu gehören Beispieldaten, vordefinierte ListView-Steuerelemente und vordefinierte CSS-Klassen. Sie können diese Vorlagen ändern oder bei Bedarf Ihre eigenen erstellen. Wenn Sie Ihre eigenen Vorlagen erstellen, sollten Sie die Prinzipien des modernen Benutzeroberflächenentwurfs befolgen und die Windows 8-Silhouette implementieren, wie im Entwicklungscenter für Windows Store-Apps unter bit.ly/IkosnL beschrieben. Wenn Sie die integrierten Visual Studio-Vorlagen verwenden, wurde dies bereits für Sie erledigt.

„ListView“ benötigt eine Item-Vorlage. Wenn Sie Daten gruppieren, wird zusätzlich eine Header-Vorlage benötigt. Die übergeordneten Elemente der Item- und Group-Vorlagen sind einfache <div>-Elemente, bei denen das Attribut „data-win-control“ auf „WinJS.Binding.Template“ gesetzt ist.

Die Header-Vorlage sollte für jede Gruppe Verknüpfungen enthalten. Wenn der Benutzer auf sie klickt, wird er zu einer Seite geleitet, auf der die zur Gruppe gehörenden Elemente aufgelistet werden. Dies ist ein Beispiel für ein übliches Master-/Detailnavigationsmuster. In Abbildung 1 enthält das als „headertemplate“ klassifizierte <div>-Element ein <button>-Element, das an den Gruppenschlüssel gebunden ist. Wenn der Benutzer auf die Schaltfläche tippt oder klickt, wird eine Seite aufgerufen, auf der die Mitglieder der Gruppe angezeigt werden.

Abbildung 1: Header-Vorlagen und Item-Vorlagen für das ListView-Steuerelement

    <div class="headertemplate" data-win-control="WinJS.Binding.Template">
      <button class="group-header win-type-x-large win-type-interactive"
         data-win-bind="groupKey: key" 
         onclick="Application.navigator.pageControl
        .navigateToGroup(event.srcElement.groupKey)" 
         role="link" tabindex="-1"
         type="button">
        <span class="group-title win-type-ellipsis" data-win-bind=
          "textContent: title"></span>
        <span class="group-chevron"></span>
      </button>
    </div>
    <div class="itemtemplate" data-win-control="WinJS.Binding.Template">
      <div class="item">
        <img class="item-image" src="#" data-win-bind=
          "src: backgroundImage; alt: title" />
          <div class="item-overlay">
            <h4 class="item-title" data-win-bind="textContent: title"></h4>
            <h6 class="item-subtitle win-type-ellipsis" data-win-bind=
              "textContent: subtitle"></h6>
          </div>
      </div>
    </div>

Die Item-Vorlage in Abbildung 1 besteht aus <div>-Tags mit einem Bild und zwei Textfeldern. Bei vielen der Daten in modernen Apps handelt es sich um Grafiken. Folglich befindet sich in der Item-Vorlage ein <img>-Element. In den Beispieldaten wird dieses Element mit einem Bild gefüllt, das nur Grau als Volltonfarbe enthält. Abbildung 2zeigt das standardmäßige ListView-Steuerelement aus dem Rasterlayout.

The Default ListView from the Grid Template, with Heading and Navigation Buttons Marked in Red
Abbildung 2: Standard-ListView aus der Vorlage „Grid“ mit rot markierten Schaltflächen für Überschriften und Navigation

Nach dem Codieren der Item- und Group-Vorlagen ist es an der Zeit, sie mit ein paar Daten zu verknüpfen.

Daten und Datenbindung mit dem ListView-Steuerelement

JavaScript und JSON arbeiten eng zusammen (JSON steht schließlich für „JavaScript Object Notation“). Sobald Sie einige JSON-Daten abgerufen haben, stellen Sie sie einfach in einem Array bereit. Das Windows.Binding.List-Objekt wird sie dann in eine für „ListView“ brauchbare Datenquelle umwandeln. Anders gesagt: Sie binden „ListView“ nicht direkt an ein Array oder eine Datenquelle, was bedeutet, dass das List-Objekt als Vermittler zwischen „ListView“ und der Datenquelle dient. Das liegt daran, dass das List-Objekt die Daten in etwas umwandelt, dessen Verwendung „ListView“ bekannt ist. „ListView“ definiert nur das Aussehen und das Layout des Rasters. Das List-Objekt bietet auch Methoden zum Suchen, Sortieren, Hinzufügen und Löschen von Membern des zugrunde liegenden Arrays.

Durch Prüfen der Datei „\js\data.js“ werden ein Data-Namespace sowie die Arrays erkannt, aus denen die Beispieldaten bestehen. Bemerkenswert und von zentraler Bedeutung ist, dass sich die beiden Arrays vermischen und eine Master-/Detailbeziehung bilden. Die Gruppeneigenschaft jedes Objekts im sampleItems-Array (Details) verweist auf die entsprechende Gruppe im sampleGroups-Array (Master), wie in Abbildung 3 gezeigt.

Abbildung 3: Beispieldaten in Arrayform in der Projektvorlage „Grid“

var sampleGroups = [
  { key: "group1", title: "Group Title: 1", 
     subtitle: "Group Subtitle: 1",
     backgroundImage: darkGray, description: groupDescription },
  { key: "group2", title: "Group Title: 2", 
     subtitle: "Group Subtitle: 2",
     backgroundImage: lightGray, description: groupDescription },
  { key: "group3", title: "Group Title: 3", 
     subtitle: "Group Subtitle: 3",
     backgroundImage: mediumGray, description: groupDescription }
];
var sampleItems = [
  { group: sampleGroups[0], title: "Item Title: 1",
    subtitle: "Item Subtitle: 1", 
    description: itemDescription,
     content: itemContent, backgroundImage: lightGray },
  { group: sampleGroups[0], title: "Item Title: 2",
     subtitle: "Item Subtitle: 2", 
     description: itemDescription,
     content: itemContent, backgroundImage: darkGray },
  { group: sampleGroups[0], title: "Item Title: 3", subtitle:
     "Item Subtitle: 3", 
     description: itemDescription,
     content: itemContent, backgroundImage: mediumGray },
  { group: sampleGroups[1], title: "Item Title: 1", subtitle:
     "Item Subtitle: 1", description: itemDescription,
     content: itemContent, backgroundImage: darkGray },
  { group: sampleGroups[2], title: "Item Title: 2", subtitle:
     "Item Subtitle: 2", description: itemDescription,
     content: itemContent, backgroundImage: mediumGray },
];

Natürlich ersetzen Sie die Beispieldaten durch Ihre eigenen, indem Sie eigene Arrays erstellen, auf JSON- oder XML-Daten zugreifen oder vielleicht einen Webdienst aufrufen. Sie müssen den Data-Namespace nicht verwenden, sondern können Ihren eigenen definieren.

Relativ weit am Anfang der Datei „data.js-“befindet sich die folgende Codezeile:

var list = new WinJS.Binding.List();

Die Listenvariable ist ein Container für ein Array. Sie können „List“ ein Array hinzufügen, indem Sie es an die Konstruktormethode von „List“ übergeben oder die Push-Methode verwenden:

generateSampleData().forEach(function (item) {
  list.push(item);
});

Hierdurch wird die Liste mit den Arraydaten gefüllt, und Sie können jetzt „list“ und „ListView“ zuordnen. Bei Verwendung des Standardvorlagencodes sollten Sie beim ersten Laden der App in der _initializeLayout-Funktion von „\js\default.js“ diese Zuordnung folgendermaßen ausführen:

listView.itemDataSource = Data.items.dataSource;
listView.groupDataSource = Data.groups.dataSource;

Die Ladedauer kann natürlich je nach Datengröße variieren. Folglich müssen Sie möglicherweise den Ladevorgang ändern. Gehen Sie beim Laden von Daten nach bestem Ermessen vor. Denken Sie dabei daran, wie wichtig die Leistung für Benutzer ist.

Beachten Sie dass die Element- und Gruppendatenquellen auf „Data.items.dataSource“ bzw. „Data.groups.dataSource“ gesetzt sind. Member mit der Bezeichnung „items“ und „groups“ des Data-Namespaces verweisen zurück auf die Funktionen, mit denen das Array mit den Daten erstellt wurde (also „groupedItems“). Die Data-Namespacedeklaration in der Datei „\js\data.js“ reflektiert diese Vorstellung und zeigt andere öffentliche Member im Namespace für die Arbeit mit Daten an:

WinJS.Namespace.define("Data", {
  items: groupedItems,
  groups: groupedItems.groups,
  getItemReference: getItemReference,
  getItemsFromGroup: getItemsFromGroup,
  resolveGroupReference: resolveGroupReference,
  resolveItemReference: resolveItemReference
});

Die Element- und Gruppenmember des Data-Namespaces zeigen auf das groupedItems-Objekt, das die Daten ordnungsgemäß erstellt hat. Alle bisher in diesem Artikel aufgeführten Inhalte in Bezug auf den Data-Namespace befinden sich in den Visual Studio-Projektvorlagen. Wenn Sie mit einem leeren Projekt starten möchten, müssen Sie die Daten anpassen, indem Sie ähnliche Datenzugriffsmethoden erstellen, anstatt sich auf die Data-Namespacemember zu verlassen.

Zu diesem Zeitpunkt ist „ListView“ mit eingerichteten Daten und Bindungen vollständig. Sie können mithilfe des Attributs „data-win-bind“ folgendermaßen Eigenschaften der Objekte in der Datenquelle an HTML-Elemente binden:

    <h4 class="item-title" data-win-bind="textContent: title"></h4>

Die vorangegangene Codezeile bindet die title-Eigenschaft an das <h4>-Element als Teil des Texts. Abbildung 1 und Abbildung 2 zeigen weitere Beispiele des Attributs „data-win-bind“ in Aktion.

Jetzt wurden der „ListView“- und der Datenzugriff fertig gestellt, und es ist an der Zeit, sich der Formatierung von „ListView“ zu widmen.

Formatieren des „ListView“-Steuerelements

Bei einer Präsentation muss auch das Format stimmen. Die WinJS-Bibliotheken enthalten einen vollständigen Satz an CSS-Regeln mit vordefinierten Formaten, die Sie überschreiben können, um „ListView“ vielfältig anzupassen. Informationen zum Formatieren von WinJS-Steuerelementen finden Sie in meinem Artikel im Oktober 2013 „Aufbau einer reaktionsfähigen und modernen Benutzeroberfläche mit CSS für WinJS-Apps“ unter msdn.microsoft.com/magazine/dn451447. Sie können das gesamte ListView-Steuerelement formatieren, indem Sie die .win-listview-CSS-Klasse überschreiben. Mithilfe der folgenden Klassenselektoren können Sie die Formatierung von „ListView“ zusammen mit den enthaltenen Elementen festlegen:

  • .win-viewport: Den Viewport der ListView formatieren. Der Viewport befindet sich dort, wo die Bildlaufleiste ist.
  • .win-surface: Den bildlauffähigen Bereich der ListView formatieren. Dieser Bereich wird verschoben, wenn ein Benutzer einen Bildlauf durchführt.

Die Elemente in „ListView“ können Sie mit den beiden folgenden Methoden formatieren. Sie können über die .win-item-Klasse Formate auf die Item-Vorlage anwenden, oder Sie können die .win-container-Klasse überschreiben. Beachten Sie, dass jedes Element in „ListView“ mehrere HTML-Elemente enthält (siehe Abbildung 1 zum Anzeigen dieser Elemente). Wie Sie Abbildung 1 entnehmen können, enthalten die <div>-Elemente, aus denen die Item-Vorlage besteht, eine .item-, .item-image-, .item-overlay-, .item-title- und .item-subtitle-Klasse. Keine von ihnen wurde in den Systemformatvorlagen (d. h. „ui-light“ und „ui-dark“) definiert, da es Ihre Aufgabe ist, sie zu formatieren.

Sie sollten ein paar potenzielle Probleme im Zusammenhang mit der Formatierung kennen, insbesondere bei der Anwendung von Rändern und Abständen auf das ListView-Steuerelement. Einzelheiten zum Formatieren von „ListView“ im Entwicklungscenter für Windows Store-Apps finden Sie unter bit.ly/HopfUg. Vergessen Sie nicht, Formate für alle unterschiedlichen Ansichtszustände Ihrer App zu erstellen.

Windows 8.1 enthält ein paar Formatierungsänderungen an „ListView“ hinsichtlich der Selektorgenauigkeit bei untergeordneten/nachfolgenden Elementen. Dies ist auf einen neuen Knoten zurückzuführen, der zur internen Struktur der Seite gehört. Folglich müssen Sie die CSS-Selektoren aktualisieren, sodass sie den .win-itembox-Klassenselektor enthalten. Das sieht folgendermaßen aus: .win-container | .win-itembox | .win-item.

Reagieren auf Ansichtszustandsänderungen in „ListView“

Eine Reaktion auf die neue angedockte Ansicht und die gefüllte Ansicht von Windows 8 ist wichtig für das Windows Store-Zertifizierungsverfahren. Die angedockte Ansicht sowie die vollständige Ansicht und die gefüllte Ansicht beschreiben, wie Benutzer mehrere Windows Store-Apps auf dem Bildschirm anordnen können. In Windows 8 können Benutzer die Größe von zwei geöffneten App-Fenstern verändern, eines in gefüllter Ansicht und eines in angedockter Ansicht. In Windows 8.1 können bis zu vier Fenster angepasst werden. Zudem sind mehr Optionen zum Anzeigen einer App vorhanden. Diese Ansichten werden in Windows 8.1 als hohe oder schmale Layouts bezeichnet und unterscheiden sich leicht von der angedockten und der gefüllten Ansicht in Windows 8.

Das bedeutet, dass Sie das ListView-Steuerelement codieren müssen, um sein Format als Reaktion auf Änderungen in App-Ansichtszuständen zu formatieren. Dieser Prozess wird als reaktionsfähiges Design bezeichnet, und Sie können es durch Verwendung von CSS-Medienabfragen umsetzen. Einen Einstieg in CSS-Medienabfragen erhalten Sie in meinem Blogbeitrag „Erstellen von Layouts für mobile Websites mit CSS-Medienabfragen“ unter bit.ly/1c39mDx.

Medienabfragen passen das ListView-Steuerelement an verschiedene Ansichtszustände an, und zwar auf eine Weise, die für variierende Bildschirmgrößen und -ausrichtungen unterschiedlicher Ansichten geeignet ist. Beim Wechsel zu hohen Ansichten muss „ListView“ folgendermaßen in eine Liste umgewandelt werden:

listView.layout = new ui.ListLayout();

Wenn der Benutzer zu einem späteren Zeitpunkt zurück in den ursprünglichen Ansichtszustand wechselt, müssen Sie „ListView“ auf ein Raster zurücksetzen:

listView.layout = new ui.GridLayout({ groupHeaderPosition: "top" });

Wenn Sie die Formatierung in den Elementen in „ListView“ beim Ändern des Bildschirms ändern möchten, fügen Sie dieser Medienabfrage in der Datei „\css\default.css“ CSS hinzu:

    @media screen and (-ms-view-state: snapped) {...}

Sie benötigen keine Medienabfrage für gefüllte oder vollständige Ansichten, weil Standardformatvorlagen verwendet werden. Sie können jedoch bei Bedarf für eine Vielzahl von Bildschirmgrößen verschiedene Medienabfragen verwenden.

„ListView“ und semantischer Zoom

Zum neuartigen Windows der Version 8 gehören neue Methoden zum Visualisieren, Navigieren und Durchsuchen von Daten. Als Konsequenz müssen Sie ganz anders an die Suche herangehen. Anstatt Ausdrücke in Suchfelder einzugeben und Ergebnislisten zu durchsuchen, können Benutzer nun mit dem semantischen Zoom Daten in übersichtlichen Abschnitten zusammenfassen.

Sie können durch eine Zusammendrückbewegung (oder Strg+Mausrad) Suchen durchführen, um Daten in aggregierter Form zu beobachten, zu schwenken oder zu verkleinern. Die Startseite von Windows ist ein gutes Beispiel hierfür, da beim Verkleinern alle verfügbaren Apps angezeigt werden. Es ist ganz einfach, den semantischen Zoom in der App zu verwenden, weil er für WinJS einfach nur ein Steuerelement ist:

    <div data-win-control="WinJS.UI.SemanticZoom">
      <!-- The control that provides the zoomed-in view goes here. -->
      <!-- The control that provides the zoomed-out view goes here. -->
    </div>

Das SemanticZoom-Steuerelement ist lediglich ein Wrapper für ein oder zwei ListView-Elemente oder möglicherweise das in Windows 8.1 neue HTML-Repeater-Steuerelement.

Zusätzliche Informationen zu „ListView“

Verwenden Sie „ListView“ nicht als Allzwecklayoutsteuerelement. Stattdessen sollten Sie für solche Zwecke das CSS-Boxmodell verwenden. In Windows 8.1 müssen Sie abwägen, ob ein ListView-Steuerelement oder ein Repeater-Steuerelement besser geeignet ist. Ein Repeater-Steuerelement ist besser geeignet, wenn das Steuerelement nicht viele Funktionen bereitstellen und nur dasselbe HTML-Design mehrmals wiederholen muss. Zum Zeitpunkt der Entstehung dieses Artikels ist Windows 8.1 als Preview erhältlich. Es könnte also weitere Änderungen an „ListView“ sowie zusätzliche API-Komponenten für Windows Store-Apps geben. Weitere Informationen zu Windows 8.1-API-Änderungen erhalten Sie im Entwicklungscenter unter bit.ly/1dYTylx.

Rachel Appel ist Beraterin, Autorin, Mentorin und frühere Microsoft-Mitarbeiterin mit über zwanzigjähriger Erfahrung in der IT-Branche. Sie nimmt an wichtigen Branchenkonferenzen wie Visual Studio Live!, DevConnections und MIX als Rednerin teil. Ihr Fachbereich ist die Entwicklung von Lösungen, bei denen geschäftliche und technologische Aspekte in Einklang gebracht werden und in denen führende Microsoft- und offene Webtechnologien zum Einsatz kommen. Besuchen Sie Rachel Appel auf ihrer Website unter rachelappel.com.

Unser Dank gilt dem folgenden technischen Experten für die Durchsicht dieses Artikels: Eric Schmidt (Microsoft)
Eric Schmidt ist ein Inhaltsentwickler im Microsoft Windows Developer Content-Team und schreibt über Windows-Bibliothek für JavaScript (WinJS). Er hat in der Vergangenheit als Angehöriger der Microsoft Office-Abteilung Codebeispiele für die Apps der Office-Plattform erstellt. Ansonsten verbringt er Zeit mit der Familie, spielt Kontrabass und erstellt HTML5-Videospiele oder verfasst Blogs über Konstruktionsspielzeug (historybricks.com).