Windows 8: Umsetzung der “SDX News” Metro-App

4. Januar 2012

Einer der vorhergehenden Blog-Beiträge hat die “SDX News” Metro-App vorgestellt. In diesem Beitrag möchte ich näher auf ein paar umsetzungsrelevante Aspekte eingehen, die bei der Entwicklung der App mit XAML/C# auf der einen und HTML5/JS auf der anderen Seite auftreten.

Metro-App Projekt-Templates

Sowohl für XAML/C# als auch HTML5/JS stehen in der Preview-Version von VIsual Studio 11 (finaler Name vermutlich Visual Studio 2012) mehrere vergleichbare Templates für Metro-Apps zur Verfügung. Als Ausgangspunkt für eigene Apps dienen dabei vor allem die folgenden beiden Templates, die bereits einen fertigen App-Rahmen liefern, der nur noch mit eigenen Daten gefüllt werden muss:

  • Grid Application: Template mit einer Übersichtsseite von Items und einer Detailseite für ein gewähltes Item. Auf der Übersichtsseite werden Items gruppiert in einem Grid dargestellt, darüber hinaus existiert eine Gruppenseite, welche die Items einer Gruppe anzeigt.
  • Split Application: In einer Split Application werden ebenfalls Gruppen von Items verwaltet. Auf der Übersichtsseite werden die Gruppen angezeigt, auf einer Detailseite werden dann zu jeder Gruppe auf der linken Hälfte der App die zur Verfügung stehenden Items der Gruppe dargestellt, auf der rechten Hälfte (daher “Split”) wird der Inhalt des aktuell gewählten Items angezeigt.

Damit eignen sich diese Templates grundlegend gut für die Darstellung von Item-Gruppen und somit auch für die “SDX News”-App, die nach Monat gruppierte Blog-Beiträge anzeigt. Ich habe mich für das “Grid Application”-Template entschieden, da mir die Darstellung der Übersichtsseite natürlich erschien:

Win8JS_SDXNews_StartScoll

.NET und WinRT im Zusammenspiel

Wird XAML/C# als Programmiermodell verwendet, so fühlt sich die Nutzung von WinRT-APIs wie die Nutzung von .NET-APIs an. Grund dafür ist die Language-Projection-Funktionalität von WinRT. Da viele Konzepte von .NET in die Entwicklung von WinRT eingeflossen sind, merkt ein Entwickler kaum, dass z.B. statt einer .NET API in seiner C#-Metro-App eine WinRT API aufgerufen wird. Früher notwendige Konzepte wie P/Invoke zum Aufruf von Betriebssystem-APIs entfallen. Lediglich am Basis-Namespace Windows.* erkennt man bei genauem Blick den Aufruf einer WinRT API. Folgendes Beispiel demonstriert den asynchronen Abruf eines Feeds mit einem SyndicationClient, der in der WinRT im Namespace Windows.Web implementiert ist:

   1: using Windows.Web.Syndication;

   2: ...

   3: SyndicationClient client = new SyndicationClient();            

   4: SyndicationFeed feed = await client.RetrieveFeedAsync(_feedUri);

Das await-Keyword wird weiter unten noch erläutert und ist ein Feature von C# 5. Ansonsten ist erkennbar, dass sich die Verwendung der WinRT für C#-Entwickler nicht viel anders anfühlt als eine zusätzliche Klassenbibliothek neben .NET. Zwar muss man diese Bibliothek auch erst erlernen und außerdem steht von .NET neben der Base Class Library (BCL) nur ein eingeschränkter Satz an Funktionalität zur Verfügung, doch gestandene .NET-Entwickler mit Erfahrung in WPF bzw. noch besser Silverlight werden sich schnell heimisch fühlen.

Standard-XAML mit Spezial-Controls

Für die Oberflächengestaltung kommt für C#- wie auch für C++-Metro-Apps das aus Silverlight und WPF bekannte XAML zum Einsatz, das für die Windows Runtime nativ re-implementiert wurde und damit eine erhöhte Geschwindigkeit aufweist. Von den Fähigkeiten und der Syntax unterscheidet sich dieses XAML nicht wesentlich von seinen Desktop-Pendants. Alle bekannten Prinzipien wie Controls, Styles, Templates, Visual States, Trigger, Data Binding etc. stehen weiterhin zur Verfügung. Dadurch kann z.B. auch das MVVM-Pattern zur Trennung der Verantwortlichkeiten zum Einsatz kommen.

Auch wenn die XAML-Fähigkeiten unter Metro bekannt sind, so sind es doch die Controls, welche die eigentliche App mit Leben füllen. Und da gibt es einige interessante Controls für Metro-Apps, die auf eine touch-optimierte Darstellung und Bedienung ausgelegt sind. Dazu gehört z.B. ein GridView, das beliebig gestaltete Items in einer Grid-Ansicht darstellt und dabei auch gruppieren kann.

Bei den neuen Controls sind zwei wichtige Eigenschaften erkennbar: Zum einen sind sie Touch-first, d.h. sie lassen sich nahtlos per Touch-Eingabe bedienen. Das heißt allerdings nicht, dass man sie nicht auch mit der Maus steuern kann. So werden bei Bewegung einer Maus automatisch Scrollbalken angezeigt, die bei Touch-Eingabe ausgeblendet sind. Zum anderen passen sich die Controls in ihrer Größe und des Renderings ihres Contents automatisch an die Auflösung des zugreifenden Devices an – ein unverzichtbarer Bestandteil für Vollbild-Apps, die auf beliebigen Geräten ausgeführt werden können. Über Visual States kann dann noch u.a. auf Wechsel der Orientierung reagiert werden.

Asynchron ist Trumpf

Bereits thematisiert wurde der hohe Grad an Asynchronität der WinRT APIs. Alle Methoden, die potentiell länger als 50ms dauern, können bei der Windows Runtime nur asynchron aufgerufen und genutzt werden. Auch hier finden sich Silverlight-Entwickler schnell wieder… Dadurch werden Metro-Apps flüssig bedienbar, zudem steigt das Potential der Verteilung von Aufgaben auf mehrere Cores der CPU.

Diese Asynchronität stellt natürlich auch hohe Anforderungen an Entwickler, die oftmals hauptsächlich eine synchrone Programmierweise gewohnt sind und für ein asynchrones Programmiermodell umdenken müssen. Werden Metro-Apps mit XAML/C# entwickelt, so erleichtern .NET 4.5, C# 5 und die Verwendung der async/await-Schlüsselwörter die asynchrone Entwicklung deutlich. async/await sind aus der Async CTP bekannt und werden fester Bestandteil von .NET 4.5. Sie erlauben Entwicklern das Schreiben von Code, der synchron aussieht, allerdings asynchron ausgeführt wird. Sind die Konzepte dahinter verstanden, so stellt dieses neue Feature einen wichtigen Bestandteil zur Entwicklung asynchroner Metro-Apps dar.

Metro-Apps mit HTML5/JavaScript entwickeln

winjsNeben XAML/C# können u.a. HTML/JavaScript verwendet werden, um Metro-Apps zu entwickeln. Solche “WinWebApps” sind dann zwar nicht plattformunabhängig (sie werden nicht einmal im Browser ausgeführt), doch es ist möglich, bestehende Web-Anwendungen in WinWebApps zu überführen und Web-Entwickler können ihr bestehendes Wissen sowie beliebige JavaScript-Bibliotheken zur Erstellung von Metro-Apps weiter verwenden.

Die Grundlage für die Erstellung von Metro-Apps mit HTML5/JS stellt die plattformabhängige WinJS-Bibliothek dar, die ein Grundbestandteil bei der Erstellung einer neuen Metro-App aus den Projekt-Templates in Visual Studio ist. Diese Bibliothek kapselt zum einen die Aufrufe an die Windows Runtime, zum anderen stellt sie Controls und Hilfsfunktionalität zur Entwicklung von WinWebApps zur Verfügung. WinJS wird in jedem HTML5/JS-Metro-Projekt in Visual Studio im Ordner “winjs” mitgeliefert, sodass sich Entwickler ihr eigenes Bild von der Funktionalität und Implementierung dieser Bibliothek machen können.

Aufbau und Ausführung einer HTML5/JS Metro-App

Einige Entwickler fragen immer wieder, wie Web-Applikationen in einer Windows-Umgebung als App ausgeführt werden. Man muss sich das so vorstellen: ebenso wie .NET-Anwendungen in einer Laufzeit-Umgebung (.NET CLR) ausgeführt werden, gestaltet sich auch die Ausführung von HTML5-Metro-Apps. Die Runtime-Umgebung dieser Apps stellt dabei die JavaScript-Engine des IE10 (Codename Chakra) dar. Es findet hier also kein Hosting vergleichbar zu ASP.NET statt, sondern die Seiten werden von der IE10-Darstellungs-Engine aus dem App-Paket gelesen und direkt dargestellt.

Entsprechend besteht ein WinWebApp-Projekt in Visual Studio auch nur aus blanken HTML-Seiten. Dinge wie serverseitiger Markup in ASP.NET oder die Razor-Syntax entfallen, da es eben keine Serverseite gibt, die Code in die Webseiten injizieren könnte. Der HTML-Markup der Webseiten ist dabei stark von der WinJS-Bilbiothek geprägt. Über die “data-win-*”-Attribute werden Standard-HTML-Elemente mit Funktionalität der WinJS-Bibliothek angereichert, welche diese Attribute ausliest und die Darstellung der Webseite entsprechend anreichert.

HTML-Templates für die Darstellung von Collection-Items

Ein Beispiel für eine solche Markup-Erweiterung stellt ein <div> dar, dem über data-win-control="WinJS.UI.ListView" mitgeteilt wird, dass es sich mit Hilfe der WinJS als ListView rendern soll. Mit Templates kann dann festgelegt werden, wie sich einzelne Elemente der ListView darstellen sollen.

Templates werden über <div data-win-control="WinJS.Binding.Template">…</div> definiert. Jeglicher Markup innerhalb des Templates wird dann für die Darstellung eines Items herangezogen. Innerhalb des Templates kann Data Binding verwendet werden, um Properties des jeweiligen Items gegen Template-Markup zu binden. Z.B. bindet <div data-win-bind="author"></div> den Autor eines Blog-Beitrags an die UI:

   1: <div class="itemTemplate" data-win-control="WinJS.Binding.Template">

   2:     <img data-win-bind="src: image" />

   3:     <div>

   4:         <div data-win-bind="textContent: title"></div>

   5:         <div data-win-bind="textContent: author"></div>

   6:         <div data-win-bind="textContent: pubDate"></div>

   7:     </div>

   8: </div>

   9:  

  10: ...

  11:  

  12: <div class="collectionList" data-win-control="WinJS.UI.ListView"></div>

Die Bindung des Templates an die ListView und das Abholen der Daten von einer Datenquelle geschieht schließlich klassisch über JavaScript.

Designaspekte von Metro-Apps

Als Gestaltungswerkzeug kann sowohl für XAML als auch für HTML5/CSS3 das bereits aus der WPF/Silverlight-Entwicklung bekannte Expression Blend zum Einsatz kommen, wobei Blend 5 auch die Gestaltung von Metro-Apps unterstützen wird. Dies ist aus meiner Sicht auch mehr als sinnvoll, denn für die Gestaltung guter Metro-Apps müssen Entwickler tiefer in die Designkiste greifen als das bei klassischen Desktop-Applikationen der Fall ist.

Aber auch inhaltlich müssen Entwickler/Designer umdenken: Vollbild-Ausführung bei unbekannter Display-Auflösung (größer oder gleich 1024x768px), Orientierungswechsel und das Anheften an der Bildschirmseite parallel zu einer anderen Anwendung stellen Herausforderungen, um die man sich bisher keine Sorgen machen musste. Und nicht zuletzt muss das Design von Metro-Apps von Grund auf neu gedacht werden. Die Apps müssen optimal per Touch bedienbar sein, dazu brauchen sie Freiraum zum Atmen, weshalb die Dichte der dargestellten Informationen nicht zu hoch sein sollte. Das sind Anforderungen, die in ähnlicher Form nur Windows-Phone-Entwicklern bekannt sein dürften.

Fazit

Dieser Artikel hat einen etwas detaillierteren Einblick in die Entwicklung von Metro-Apps mit XAML/C# und HTML5/JavaScript gegeben. Generell ist die Lernkurve für gestandene .NET-Entwickler zur Erstellung von Metro-Apps mit XAML/C# nicht sehr steil, vor allem wenn man Silverlight und/oder Silverlight für Windows Phone beherrscht. Dann lassen sich viele Konzepte auf die Erstellung von Metro-Apps übertragen, auch viele Features des .NET-Frameworks sind weiterhin nutzbar und die Verwendung der WinRT fühlt sich an wie die Verwendung einer normalen .NET-API.

Ebenso wie .NET-Entwickler bei XAML/C# werden sich Web-Entwickler schnell in dem HTML5/JavaScript-Modell von Windows 8 zurechtfinden und Metro-Apps erstellen können. Sind die WinJS-Bibliothek und die Nutzung dieser bzw. die Konzepte dahinter (Controls, Data Binding, Templating, …) verstanden, so werden sich damit komfortabel Metro-Apps entwickeln lassen. Statt .NET steht Entwicklern dabei jede beliebige JavaScript-Bibliothek zur Verfügung, die im Web verfügbar sind.

Die Wahl zwischen XAML/C# und HTML5/JS (bzw. natives C++ als dritte Option) ist damit abhängig von verschiedenen Faktoren. wenn eine Anforderung das Einbinden von HTML-Inhalten ist, so wird man natürlicherweise eher auf HTML/JS setzen. Hat man ein Team von klassischen .NET/Silverlight-Entwicklern, ist XAML/C# hingegen wahrscheinlich die bessere Wahl. Pauschal lässt sich das nicht entscheiden, dies ist immer vom jeweiligen Projekt-Kontext abhängig.

Diese kurze Beitragsserie zu Windows 8 sollte einen ersten Einblick in das neue Betriebssystem von Microsoft und die Entwicklung darunter geben. Tiefergehende Informationen wird ein Artikel zu Windows 8 und der Windows Runtime geben, den ich aktuell schreibe und der voraussichtlich in der dotnetpro 03/2012 erscheinen wird.