Halo für Windows Phone 8 & Windows 8

Von Robert John Autor Feed 6. June 2013 11:26
Diesmal ein kurzer Blog-Eintrag von mir, mit nur einem Wort: WAU! Halo to hit Windows 8 and Windows Phone 8 in July! Endlich beginnt der Sommer :-) ….

Apps zu einem bestimmten Datum in den Windows Store veröffentlichen

Von Rina Ahmed Autor Feed 15. May 2013 16:00
In diesem Post wird gezeigt, wie man gewährleisten kann, dass Windows Store Apps an einem bestimmten Datum veröffentlicht werden. [More]

BuildWindows Second Chance

Von Toni Pohl (Gastblogger) Autor Feed 14. May 2013 00:05
Dieses Jahr war die Microsoft BuildWindows Konferenz in S.F. in weniger als drei Stunden ausgebucht. Für alle jene, die gerne hingefahren wären, aber keinen Platz mehr gefunden haben, eröffnet der Veranstalter am 15. Mai eine zweite Chance. Mit der Ankündigung “We made more room” werden weitere Tickets verkauft. [More]

Pizza Tour Windows 8 Development Nachlese

Von Petra Kleiber Autor Feed 7. May 2013 12:32
Für all jene die uns bei der diesjährigen Frühjahrs - Pizzatour nicht besuchen konnten und jene die einfach nur in den Unterlagen schmökern und nachlesen wollen: Die Nachlese mit den Samples und Präsentationsunterlagen ist online verfügbar!    

Persistente Datenspeicherung für Windows 8 Apps in HTML5/Javascript

Von Christian Vorhemus Autor Feed 1. May 2013 11:58
In diesem Tutorial soll gezeigt werden, wie Daten in einer Windows 8 App mittels IndexedDB gespeichert und wieder ausgelesen werden können. Als Beispiel dient dazu eine einfache Benutzerverwaltungs-App, mit der Benutzer angelegt und wieder gelöscht werden. Ein kurzer Überblick über IndexedDB Im Zuge der immer vielfältigeren Möglichkeiten, die mit klassischen Webapplikationen geschaffen werden können, wurden auch Stimmen nach effizienten clientseitige Speichermöglichkeiten laut. Bis dato war die persistente Datenspeicherung hier so gut wie gar nicht möglich: Lediglich Cookies erlaubten das Schreiben und Lesen von Parametern. Diese waren aber allein schon aufgrund der geringen erlaubten Speichergröße maximal für einige zu speichernden Einstellungen auf Webseiten zu gebrauchen. Mozilla wagte hier einen Vorstoß und führte als eine der Ersten für ihren Browser eine Index-basierte Datenbank ein. Schließlich wurde die Spezifikation für eine solche Datenbank vor gut einem Jahr vom W3-Konsortium verabschiedet und ist offiziell Bestandteil von HTML5. Verwendet werden kann IndexedDB nicht nur mit Browsern wie Internet Explorer 10, Chrome oder Firefox sondern dank der weitreichenden HTML5-Unterstützung auch mit Windows 8! Schritt 1: Projekt öffnen und vorbereiten Zunächst öffnen wir in Visual Studio 2012 ein neues Projekt und wählen den Unterpunkt JavaScript > Windows Store > Navigations-App aus. (Hinweis: Wer neu in der Welt der HTML5/Javascript-Apps ist, mag sich als Einstieg vielleicht zuvor dieses Tutorial ansehen) Ist das Projekt angelegt, navigieren wir in den Ordner pages/home und öffnen home.html. Dort ändern wir zunächst den style von ui-dark.css auf ui-light.css, schreiben im span-tag der Klasse “pagetitle” “Benutzerverwaltung” statt “Willkommen bei DBSample” und löschen die Zeile “Hier Inhalt einfügen” zwischen den <p></p>-Tags. Als nächstes fügen wir die AppBar hinzu, die sich bei einem Rechtsklick in die App bzw. auf Touch-Devices von einer Wischbewegung vom unteren Rand nach oben öffnet. Dazu kopieren wir folgenden Code und fügen ihn in die home.html-Datei knapp über dem </body>-Tag ein: <div id="appbar" data-win-control="WinJS.UI.AppBar"> <button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'removeUser', label:'Löschen', icon:'delete'}" type="button"></button> <button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'addUser', label:'Neu', icon:'add'}" type="button"></button> </div> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Wenn wir nun auf F5 klicken um die App zu starten und danach mit dem rechten Maustaste in die App klicken, sollte sich die noch funktionslose AppBar öffnen. Um die AppBar zu stylen, können wir uns übrigens der .win-appbar-property bedienen. Um den AppBar-Hintergrund grau zu färben, kopiere man nachfolgenden Code in die home.css-Datei: .win-appbar { background-color: #CCCCCC; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Im nächsten Schritt legen wir ein Fenster an, das sich öffnet, wenn der User auf den “Neu”-Button in der AppBar klickt. Dazu schreiben wir ein <div>, in dem sich Text-inputs sowie Buttons befinden. Diesen Code fügen wir gleich nach dem <body>-Tag in home.html hinzu: <div id="addDiv"> <h2>Neuen Benutzer hinzufügen</h2><p></p> <table> <tr><td>Name:</td><td><input type="text" id="username" /></td></tr> <tr><td>Alter:</td><td><input type="number" id="age"/></td></tr> <tr><td>Typ:</td><td><select id="type"><option>User</option><option>Administrator</option> </select></td></tr> </table> <p></p> <input type="button" id="addEntry" value="Eintragen"/> <input type="button" id="close" value="Schließen"/> </div> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Um das <div> mittig auszurichten, kopiere man folgenden Code in die home.css-Datei: #addDiv { color:black; display:none; height:250px; position: absolute; width:530px; z-index: 50; border: 5px solid grey; top: 50%; left: 50%; margin-top: -125px; margin-left: -287px; background-color:white; font-size:20px; padding-top:20px; padding-left:20px; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Das div wird zunächst nicht angezeigt (display:none;), kümmern wie uns nun um den Öffnen/Schließen-Mechanismus. Dazu öffnen wir die home.js-Datei. In Zeile 7 sehen wir den Eintrag “ready: function (element, options)”. In dieser Funktion wird die Seite initialisiert, hier werden wir auch unsere EventListener anlegen, damit bei Klicks auf die Buttons der AppBar das Fenster geöffnet wird. In dieser Funktion legen wir die folgenden drei EventListener an: document.getElementById("addEntry").addEventListener("click", addEntry); document.getElementById("close").addEventListener("click", closeWindow); document.getElementById("addUser").addEventListener("click", openWindow); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Wird auf den Button mit der ID “addEntry” geklickt, wird die Funktion addEntry ausgeführt; Äquivalentes gilt für die anderen zwei Listener. Legen wir nun die openWindow() und closeWindow() Funktionen an. Wir kopieren den nachfolgenden Code und fügen ihn kurz nach der WinJS.UI.Pages.define-Funktion ein. function openWindow() { document.getElementById("appbar").winControl.hide(); var elm = document.getElementById("addDiv"); elm.style.display = "block"; WinJS.UI.Animation.fadeIn(elm); }   function closeWindow() { var elm = document.getElementById("addDiv"); elm.style.display = "none"; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Unsere home.js Datei sollte bis jetzt wie folgt aussehen:   Detail am Rande: In der openWindow-Funktion bedienen wir uns der von WinJS bereitgestellten fadeIn-Funktion um einen Fade-Effekt zu erzeugen. Eine Fade-Out-Animation gibt es auch – fadeOut heißt hier das Pendant. Wenn wir nun auf den “Neu”-Button in unserer AppBar klicken, wird unser div geöffnet, die sich zentriert in der Bildschirmmitte befindet: Schritt 2: Datenbank anlegen Mit IndexedDB werden Objekte in Form eines key-value-pairs gespeichert, am häufigsten wird zu diesem Zweck die JSON- Notation verwendet. Würden wir mit einer relationalen Datenbank arbeiten, müssten wir für unsere Benutzerverwaltung zunächst die Datenbank erstellen. Das könnte für relationale Datenbanken in MySQL etwa so aussehen: CREATE DATABASE userDatabase; In unserer IndexedDB legen wir eine Datenbank wie folgt an: var request = window.indexedDB.open("userDatabase ", 1); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Der erste Parameter ist der Datenbankname, der zweite gibt die Versionsnummer an (immer wenn sich das Datenbankschema ändert, muss sich auch die Versionsnummer ändern). Die open()-Funktion selbst retourniert ein Request-Objekt, das mehrere Zustände beschreiben kann: Success, Error, Blocked und UpgradeNeeded wobei letzterer Zustand immer dann aufgerufen wird, wenn sich die Versionsnummer ändert. Um die Datenbank anlegen bzw öffnen zu können, fügen wir folgende Funktion kurz oberhalb von openWindow in home.js ein: var db = null; function openDatabase() { var dbRequest = window.indexedDB.open("userDatabase", 1); dbRequest.onerror = function () { console.log("Fehler beim Erstellen der Datenbank"); }; dbRequest.onblocked = function () { console.log("Datenbank blockiert"); };   dbRequest.onsuccess = function (evt) { db = evt.target.result; showEntries(); };   dbRequest.onupgradeneeded = function (evt) { if (db) { db.close(); } db = evt.target.result; var txn = evt.target.transaction; var bookStore = db.createObjectStore("userlist", { keyPath: "id", autoIncrement: true }); bookStore.createIndex("username", "username", { unique: false });   txn.oncomplete = function () { }; }; }   function showEntries() {   } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Die openDatabse()-Funktion soll bei der Initialisierung der Seite aufgerufen werden, wir fügen daher den Eintrag openDatabase(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } kurz unterhalb des EventListeners document.getElementById("addUser").addEventListener("click", openWindow); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } hinzu. In relationalen Datenbanken würden wir im nächsten Schritt das Datenbankschema in SQL anlegen, was (in MySQL) etwa so aussehen könnte: CREATE TABLE user (   id INT PRIMARY KEY,   username VARCHAR(40) ,   age INT,   type ENUM(‘Administrator’, ‘User’) ); Mit diesem Code legen wir also eine Tabelle an, in die wir nun Daten ablegen können. Mit IndexedDB kreieren wir im Unterschied dazu Objekt-Storages. Das ist nichts anderes als ein Speicherplatz mit einem zugewiesenen Namen, in den Objekte (als key-value-pair) abgelegt werden können. Ein “richtiges” Schema für Tabellen wie bei relationalen Datenbanken gibt es hierbei nicht. Der entsprechende Code um ein solches Objekt-Storage für die Benutzerverwaltung anzulegen, könnte in etwa wie folgt aussehen: db.createObjectStore("users",{keyPath: "id"}); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } keypath gibt hierbei jenen value an, mit der der Datensatz eindeutig identifiziert werden kann. Unsere Datenbank steht nun bereit um Daten aufzunehmen, fügen wir nun eine Funktion addEntry() hinzu. Diese können wir oberhalb von openDatabase einfügen: var user = new WinJS.Binding.List(); WinJS.Namespace.define("UserList", { user: user });   function addEntry() {   var username = document.getElementById("username").value var age = document.getElementById("age").value var type = document.getElementById("type").value var id = 0;   if (user.length != 0) { user.dataSource.itemFromIndex(user.length - 1).done(function (item) { id = item.data.id + 1; }); }   var item = { "id": id, "username": username, "age": age, "type": type, "picture": "/images/user.png" };   var transaction = db.transaction("userlist", "readwrite"); var addRequest = transaction.objectStore("userlist").add(item); addRequest.onsuccess = function (evt) { user.push(item); } closeWindow(); }   .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Um Daten löschen zu können, legen wir nun in der home.js-Datei einen weiteren EventListener in der ready-Funktion an: document.getElementById("removeUser").addEventListener("click", deleteEntry); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } … die zugehörige deleteEntry()-Funktion sieht so aus, diese kopieren wir unter die addEntry-Funktion: function deleteEntry() { var listView = document.getElementById("itemsListView").winControl;   listView.selection.getItems().done(function (currentSelection) { currentSelection.forEach(function (selectedItem) {   var dbKey = selectedItem.data.id; var listViewKey = selectedItem.key; var transaction = db.transaction("userlist", "readwrite"); var deleteRequest = transaction.objectStore("userlist").delete(dbKey);   deleteRequest.onsuccess = function () { user.dataSource.remove(listViewKey); } deleteRequest.onerror = function () { } }); }); document.getElementById("appbar").winControl.hide(); } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Schritt 3: ListView erstellen Im letzten Schritt haben wir unter anderem die Zeile var user = new WinJS.Binding.List(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } hinzugefügt. Diese so definierte Liste “user” verwenden wir, um darin alle Benutzer zu speichern, die wir aus der Datenbank auslesen um diese schließlich zu unserer ListView hinzuzufügen. Die ListView selbst ist nichts anderes als eine von WinJS zur Verfügung gestellte control um eine Ansammlung an Items im Sinne des "Modern UI” anzuzeigen. Um unsere Liste “user” beim Initialisieren zunächst mit den Daten aus der Datenbank zu füllen, ersetzen wir die leere showEntries()-Funktion, die sich bereits in unserer home.js-Datei befindet, mit folgendem Code: function showEntries() { if (db) { var request = []; var transaction = db.transaction("userlist", "readonly"); var store = transaction.objectStore("userlist");   var index = store.index("username"); index.openCursor().onsuccess = function (event) { var cursor = event.target.result; if (cursor) { user.dataSource.insertAtEnd(null, cursor.value); cursor.continue(); } }; } }   Nun müssen wir unsere Liste “user” allerdings auch anzeigen. Zu diesem Zweck fügen wir den folgenden Code in unsere home.html-Datei kurz nach “<section aria-label="Main content" role="main">” hinzu: <div id="mediumListIconTextTemplate" data-win-control="WinJS.Binding.Template" style="display: none"> <div class="mediumListIconTextItem"> <img src="#" class="mediumListIconTextItem-Image" data-win-bind="src: picture" /> <div class="mediumListIconTextItem-Detail"> <b>Username:</b> <span data-win-bind="innerText: username"></span><br /> <b>Alter:</b> <span data-win-bind="innerText: age"></span><br /> <b>Accounttyp:</b> <span data-win-bind="innerText: type"></span> </div> </div> </div> <div id="itemsListView" data-win-control="WinJS.UI.ListView" data-win-options="{itemDataSource : UserList.user.dataSource, itemTemplate: select('#mediumListIconTextTemplate')}"> </div> Hier wird die ListView angelegt und mit einem entsprechenden Template versehen, sodass unsere Daten formatiert ausgegeben werden. Wenn wir die App testen, auf “Neu” klicken und einen Benutzer anlegen, können wir schon Einträge speichern, allerdings sieht der Eintrag noch etwas unfömig aus. Um das zu ändern, fügen wir zunächst folgendes Bild in den /image-Folder hinzu: Außerdem fügen wir folgenden Code in unsere home.css ein: #itemsListView { height: calc(100% - 80px); width:calc(100% - 90px); border: 0px solid red; }   #itemsListView .win-container:not(.footprint):not(.hover) { background-color: transparent; color:black; border: 1px solid gray; }   .mediumListIconTextItem { width: 282px; height: 70px; padding: 5px; overflow: hidden; display: -ms-grid; }   .mediumListIconTextItem img.mediumListIconTextItem-Image { width: 60px; height: 60px; margin: 5px; -ms-grid-column: 1; }   .mediumListIconTextItem .mediumListIconTextItem-Detail { margin: 5px; -ms-grid-column: 2; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Mit diesem Schritt sind wir bereits fertig: Wir können nun Benutzer hinzufügen indem wir in der AppBar auf “Neu” klicken. Wenn wir Benutzer löschen wollen, klicken wir mit der rechten Maustaste auf die jeweiligen Einträge um sie auszuwählen und dann nochmals mit der rechten Maustaste um auf den “Löschen”-Button klicken zu können. Ein nettes Feature wäre noch, wenn sich bei einer Auswahl an Einträgen die AppBar automatisch öffnet, diese Funktion fügen wir im finalen Schritt 4 noch hinzu. Schritt 4: Öffnen der AppBar durch selectionchanged-Events Zunächst fügen wir wieder einen EventListener in der ready-Funktion in home.js ein: document.getElementById("itemsListView").winControl.addEventListener("selectionchanged", changedSelection); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Danach fügen wir die nachfolgende changedSelection-Funktion zB unterhalb von deleteEntry hinzu: function changedSelection(eventObject) { document.getElementById("appbar").winControl.show(); } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } In Worten gesprochen passiert hier folgendes: Immer dann, wenn sich die aktuelle Auswahl (Rechtsklick) der itemsListView ändert, öffnet sich die AppBar. Den Quellcode dieses Projekts gibt es auf http://www.wissen-kompakt.at/codefest/DBSample.zip zum Download! Los gehts! Dieses Tutorial ist nur ein Einstiegspunkt für weitere eigene Entwicklungen. Die Möglichkeiten, diese App zu erweitern sind unbegrenzt und reichen zB von einem FilePicker, um statt dem User-Platzhalter-Icon Fotos von Benutzern zu speichern, bis hin zu automatischer Datensynchronisation, um auf allen Geräten stets den gleichen Datenstand zu haben. Nur empfehlen kann man abschließend die umfangreichen Dokumentationen und Codebeispiele auf msdn.microsoft.com, die einen tieferen Einblick in die Materie bieten.

Datensynchronisation zwischen mehreren Windows 8 Geräten

Von Christian Vorhemus Autor Feed 23. April 2013 10:13
Wie lassen sich Einstellungen in einer App zwischen mehreren Geräten (auf denen die gleiche App installiert ist) synchronisieren? Dass es technisch möglich ist, steht außer Zweifel, aber bei Windows 8 genügen – und das ist kein Marketing-Spruch – nur zwei Zeile Code um diesen Abgleich durchzuführen. Wer in der Medienbranche arbeitet oder auf diesem Gebiet bewandert ist, hat sicherlich in den letzten Jahren den Begriff des „Second Screen“ aufgeschnappt. Er beschreibt die Praktik, neben dem Fernsehgerät noch ein zweites Device bei sich zu haben, um parallel zum Programm über selbiges zu bloggen, twittern oder chatten. Bisher haben Notebooks oder Netbooks diese Position wacker verteidigt, ehe sie in letzter Zeit von Tablets abgelöst wurden, die sich bequemer am Sofa als Zweitgerät verwenden lassen. Mit dieser durchaus immer häufiger anzutreffenden Symbiose zwischen Tablet und Desktop-PC wird allerdings wieder ein altes Problem akut: Die Synchronisation zwischen verschiedenen Geräten. Natürlich ist es möglich, jedes Gerät für sich als eigenes Universum zu betrachten mit völlig eigenständigen Einstellungen. Jedoch werden sich viele Menschen in den meisten Fällen wünschen, dass ihre Kontaktdaten, ihre Bilder oder ihre Device-Einstellungen sowohl am Desktop als auch am Tablet in der exakt gleichen Form vorhanden sind – schließlich bewirbt Microsoft Windows 8 damit, die Welten des Desktop und Tablets vereinen zu wollen. Freundlicherweise hat es Microsoft auch Programmierern sehr einfach gemacht, eine solche Synchronisation durchzuführen, das Zauberwort lautet hier: Roaming Settings. Neben einem MSDN-Eintrag zu diesem Thema (aufzufinden hier) existiert auch eine nette Dokumentation inklusive Code-Beispiel hier. Wie es funktioniert Obwohl man leicht annehmen könnte, die paar Zeilen Code könnten doch nicht ausreichen, um Daten zu synchronisieren, ist das tatsächlich der Fall: Um Einstellungen zwischen Apps auf mehreren Geräten zu synchronisieren, sind genau zwei Zeilen Code notwendig – egal ob in Javascript, C# oder in VB! Nehmen wir an, Benutzerin Alice schmökert gerade in einem eBook auf ihrem PC ehe sie erschrocken die fortgeschrittene Zeit erblickt und eilig ihre Sachen packt, um nicht zu spät zum Windows Dev-Camp zu kommen (Randnotiz: Wer es Alice gleich tun und ein solches DevCamp besuchen will, sei hierauf verwiesen). Wäre es nicht wunderbar, wenn Alice in der Straßenbahn auf ihrem Tablet ihr eBook dort weiterlesen könnte, wo sie am PC aufgehört hat? Kein Problem: Man baue als Programmierer folgende Zeile Code ein und update diese Einstellungen immer dann, wenn der User die Seite des eBooks ändert: Windows.Storage.ApplicationData.Current.RoamingSettings.Values["currentPage"] = 42; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Woher weiß nun meine App, wie und mit wem sie sich synchronisieren soll? Prinzipiell knüpfen die RoamingSettings hier an das Microsoft-Konto an, mit dem man am PC angemeldet ist. Sobald man mit dem gleichen Microsoft-Konto (das heißt, mit gleicher Mailadresse) auf einem anderen PC angemeldet ist, kommt Synchronisation grundsätzlich in Frage. Zusätzlich dazu hat jede App in Windows 8 eine eindeutige ID. Das bedeutet nun grob gesagt: Der Wert „currentPage“ der von der eBook-Reader-App mit der ID X42 am PC von Alice mit der Mailadresse alice@wunderland.at auf dem Desktop-PC gesetzt wird, wird in die Cloud geladen. Meldet sich Alice auf ihrem Tablet mit derselben Mailadresse an und besitzt sie auch dort die App mit der ID X42, so erfragt die Runtime im Hintergrund automatisch, ob für diese App RoamingSettings vorliegen und stellt diese zur Verfügung. Der Programmierer muss sie dann lediglich mit int page = roamingSettings.Values["currentPage"]; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } einlesen und kann damit weiterarbeiten. Wer ganze Dateien synchronisieren will, für den bietet der RoamingFolder die passende Funktionalität. Setup für den User Kurioserweise ist es für Programmierer in Windows 8 fast einfacher, Daten zu synchronisieren als für den User, dieses Feature schlussendlich zu verwenden, denn die entsprechenden Einstellungen sind etwas versteckt. Zunächst müssen wir dazu in die PC-Einstellungen wechseln und – sofern noch nicht vorhanden – mit einem Klick auf „Zu einem Microsoft-Konto wechseln“ ein Microsoft-Konto einrichten. Dazu benötigen wir nur das aktuelle PC-Passwort, eine Mailadresse sowie wiederum ein Passwort dafür. Ist das getan, fragt uns Windows skeptisch, ob wir uns wirklich vertrauen können. Der letzte Satz hört sich seltsamer an, als er wirklich ist, denn theoretisch könnten wir ja auch eine x-beliebige E-Mail-Adresse verwenden und diese zur Synchronisation verwenden – dem schiebt Windows einen Riegel vor. Um sicherzustellen, dass wir auch der Eigentümer der Mailadresse sind, klicken wir auf „Diesem PC vertrauen“, worauf wir einen Zahlencode an unsere Mailadresse zugeschickt bekommen, den wir in ein Browserfenster eingeben müssen. Ist das erledigt, werden unsere Einstellungen nun online gespeichert und immer dann, wenn ein Device online geht, abgeglichen. Nun kann Alice in aller Ruhe ihr eBook fertig lesen und danach mit Bob am DevCamp über dieses nette Feature plaudern.

Integrieren des Search Charm in eine Windows Store App

Von Rina Ahmed Autor Feed 16. April 2013 12:29
Dieser Artikel demonstriert wie man Suche in eine Windows Store App einbauen kann. Es werden dabei drei Dinge gezeigt:
1) Suche während die App läuft
2) Einbindung von Suggestions beim Eintippen des Suchbegriffs
3) Starten der App durch externe Suche [More]

Spracherkennung mit Windows mit C#

Von Andreas Pollak Autor Feed 11. April 2013 15:06
Eine sehr gute Spracherkennung gibt es eigentlich schon seit Windows Vista. Natürlich damit auch auf Windows 7 und Windows 8. Vor Kurzem wurde dazu ein c00ler Artikel auf Codeproject gepostet wie Du die Speech-API aus .NET in deinen Projekten nutzen kannst. Lies mehr auf codeproject.com zur Spracherkennung mit C#. Andreas Pollak Product Marketing Manager Visual Studio 2012 (Entwicklungs- und Testwerkzeuge) Leader im Magic Quadrant von Gartner für ALM

Die Windows 8 Development Pizza Tour macht wieder an 4 Locations Halt

Von Petra Kleiber Autor Feed 4. April 2013 20:39
Unsere technischen Experten Rina Ahmed und Andi Schabus touren mit Ihren Windows 8 Development Sessions im Rahmen unserer etablierten Pizza Tour durchs Land und machen an vier Uni/FH -  Locations Halt: FH Wr. Neustadt  - 18. April FH Joanneum/Kapfenberg – 23. April FH Hagenberg – 25. April FH Technikum Wien – 29. April Gemeinsam mit unseren Student Partnern zeigen Sie Euch exklusiv und aus erster Hand die Windows Plattform, geben Euch die Chance mit Andi im Quick Lab Eure eigene App auf Herz und Nieren zu checken und stehen Euch Rede und Antwort zu Fragen rund um Windows 8 und Windows Phone 8 Apps, sowie Windows Azure. Rina und Andi zeigen euch Neues zum Thema Development. Die Student Partner stehen für ein “Schwätzchen” (O-Ton der Student Partner) rund um Microsoft zur Verfügung, Pizza und das eine oder andere Goodie gibt es natürlich auch.   Alle Infos rund um die Pizza Tour sowie die Links zur Anmeldung findet Ihr auf der unserer Pizza-Website.

buildwindows Windows Developer Konferenz

Von Toni Pohl (Gastblogger) Autor Feed 28. March 2013 21:51
Auch dieses Jahr wird es wieder eine Windows-Entwickler-Konferenz geben: buildwindows findet im Juni 2013 in San Francisco statt. Interessant: Die Website buildwindows.com versucht durch Scrollen eine kleine Geschichte zu erzählen und Spannung aufzubauen. [More]

Kochrezept für Windows 8 Apps in HTML5/Javascript

Von Christian Vorhemus Autor Feed 20. March 2013 15:05
Man nehme eine Portion Motivation und eine gute Entwicklungsumgebung (Visual Studio 2012), würze alles mit einer Prise Kreativität und fertig ist die Windows 8 App! In dieser Kochshow sollen Konzepte und Sourcode gezeigt werden, mit denen Apps für Windows 8 sehr schnell und einfach in HTML5/Javascript geschrieben werden können. Voraussetzung für dieses kleine Tutorial sind nur Basiskenntnisse in HTML und Javascript, Erfahrung in höheren Programmiersprachen ist nicht nötig. Ziel ist es, dem geneigten Leser einen Überblick über die Entwicklung von Windows 8 Apps in HTML und Javascript zu verschaffen, einige Hintergrundinformationen zu Windows 8 typischen Funktionalitäten zu liefern und Code vorzustellen, mit dem bereits die ersten Apps erstellt werden können. Wir halten uns in diesem Tutorial an folgendes Rezept: Die Struktur eines Projekts Anonyme Funktionen und WinJS Formelemente, Event-Listener und Debugging Navigation und Seiten Pimp your site with CSS Die weiteren Schritte   Die Struktur eines Projekts Um den Aufbau einer App gleich am Praxisobjekt erforschen zu können, öffnen wir Visual Studio 2012 (Visual Studio Express 2012 für Windows 8 kann hier heruntergeladen werden), klicken oben links auf Datei > Neu > Projekt. Im nun erscheinenden Fenster wählen wir links im Menü “installiert” den Unterpunkt “Vorlagen” und als Sprache “JavaScript” aus. Danach klicken wir auf “Windows Store” und wählen “Navigations-App”. Weiter unten in diesem Fenster können wir im Textfeld “Name” unser Projekt noch benennen und mit einem Klick auf “OK” tauchen wir bereits ein, in die Welt der App-Entwicklung. Nach kurzer Ladezeit wird automatisch die default.js-Datei im Codefenster angezeigt, rechts daneben sehen wir den Projektmappen-Explorer, in dem die verschiedensten Ordner und Dateien unseres Projekts angezeigt werden. Apps können aus mehreren Seiten bestehen, etwa einer Hauptseite mit mehreren Items und Unterseiten, auf denen detaillierte Infos zu den Items eingeblendet werden. Die Seiten einer App befinden sich im Ordner “pages”, wobei jede Seite einen eigenen Unterordner erhält. Standardmäßig wird für uns gleich eine erste Seite erstellt, die “home” lautet. Eine Seite wiederum besteht aus 3 Dateien: Eine HTML-Datei, eine CSS-Datei und eine JS-Datei. Während HTML und CSS für das Design zuständig sind (ähnlich wie XAML-files) befindet sich die Steuerungslogik in den JS-Dateien (ähnlich wie die “code behind”-Dateien in C#). Wenn ein Benutzer unsere App öffnet, gelangt er aber nicht gleich auf unsere home.html-Seite, sondern stets auf default.html. In dieser Datei kann selbst Inhalt stehen, oder auf eine andere Seite verwiesen werden. Dies passiert mit folgendem Code: 1: <div id="contenthost" data-win-control="Application.PageControlNavigator" 2: data-win-options="{home: '/pages/home/home.html'}"></div> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Zwei Dinge sind hier interessant: Zum einen die data-win-control property, zum anderen die data-win-options property. Mittels data-win-control weisen wir unserem <div>-Element eine spezielle Windows 8 spezifische Eigenschaft zu – in diesem Fall soll das <div> als Navigationselement dienen. Es existieren eine Reihe an vordefinierten controls, die unsere leeren <div>-Tag wie durch Zauberhand in allerlei nützliche Steuerungselemente verwandeln, zum Beispiel können durch ein control aus einem <div> rating-Sternen erzeugt werden, was mit folgendem Code funktioniert: 1: <div data-win-control="WinJS.UI.Rating"></div> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Mit data-win-options werden weitere Optionen für den in data-win-control definierten control angegeben. In unserem Beispiel wird hier auf die Seite “home” verwiesen, die sich im Ordner “/pages/home/home.html” befindet. Im Ordner css und im Ordner js befinden sich Dateien, die den Namen “default” tragen. Hier können Funktionen bzw. Styles definiert werden, die für die gesamte App gültig sind. Ein Beispiel dafür sind App-Bars: Die App-Bar soll auf jeder Unterseite meiner App erscheinen, sobald ich die rechte Maustaste klicke, daher definiere ich sie in meiner default.html. Zusammenfassend lässt sich also sagen: default.html sowie die im Ordner js befindliche default.js und die im css-Ordner befindliche default.css definieren den “Rahmen” und das Layout, das für alle Unterseiten der App gültig ist. Seitenspezifische styles werden in den im Ordner “pages” befindlichen css-Seiten definiert. … und wie in allen App-Projekten, findet sich auch in einem JavaScript-Projekt die Datei package.appmanifest in der unter anderem die Hintergrundfarbe für den SplashScreen vergeben wird oder ausgewählt werden kann, welche Funktionen die App nutzen darf (Internetverbindung, Kamera, Mikrofon, …). Anonyme Funktionen und WinJS Werfen wir gleich einen Blick in die JS-Datei unserer home-Seite: Durch einen Doppelklick auf die entsprechende Datei können wir uns den Code anzeigen lassen: Wir sollten folgenden Code sehen: 1: (function () { 2: "use strict"; 3:   4: WinJS.UI.Pages.define("/pages/home/home.html", { 5: // Diese Funktion wird immer aufgerufen, wenn ein 6: // Benutzer zu dieser Seite wechselt. Sie 7: // füllt die Seitenelemente mit den Daten der App auf. 8: ready: function (element, options) { 9: // TODO: Die Seite hier initialisieren. 10: } 11: }); 12: })(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Hier wird eine (anonyme) Funktion definiert, die automatisch aufgerufen wird, wenn der User die Seite home.html anzeigen lässt. Mit den zwei Wörtern “use strict” wird definiert, dass unser Code im “strict mode” ausgeführt wird und damit bestimmte Regeln eingehalten werden müssen, damit der Code kompiliert werden kann (zB müssen alle Variablen mit dem Schlüsselwert var deklariert werden, bevor ihnen ein Wert zugewiesen werden kann). In Zeile 4 wird auf WinJS verwiesen. WinJS ist eine Javascript-Bibliothek die eine Reihe an Funktionalitäten zur Verfügung stellt um uns die Arbeit zu erleichtern. Hier wird eine PageControl definiert, damit wir – vereinfacht gesagt – mit unserer home.html-Seite interagieren können. In Zeile 8 befindet sich die Funktion ready. Code, der in dieser Funktion steht wird aufgerufen, während die Seite geladen wird. Das bedeutet, hier sollten zB Event-Listener (dazu siehe sogleich) definiert werden. Formelemente, Event-Listener und Debugging Die Grundfunktionalität einer jeden App ist es, die Aktionen, die ein Benutzer ausführt aufzufangen und entsprechende weitere Schritte zu setzen. Immer wenn ein User auf einen Button klickt oder eine Wischgeste ausführt, möchten wir diese Aktionen empfangen können, und auf die Eingaben reagieren. Wie in vielen anderen Frameworks, wird auch für Windows 8 das Konzept der Event-Listener verwendet, um Eingaben zu registrieren. Wechseln wir zurück in Visual Studio und wagen wir uns an die erste simple Interaktion, die wir implementieren: Immer ein ein User auf einen Button klickt, soll ein Eintrag in die Javascript-Konsole geschrieben werden. Da die HTML-Seiten das User-Interface darstellen, legen wir unseren Button auch in der home.html Datei an. Dazu löschen wir den Eintrag 27: <p>Hier Inhalt einfügen</p> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } aus Zeile 27 und fügen stattdessen folgenden Code ein: 27: <button id="beispielbutton1">Beispielbutton</button> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Der <button></button> Tag definiert einen simplen Button der mehr oder weniger nur aus einem weißen Rechteck mit Text besteht. Äußert wichtig ist für unsere Zwecke die property id, mit der unser Element für den Event-Listener eindeutig identifizierbar wird. Wer eine schnelle Übersicht sucht, welche Elemente eingefügt werden können, möge in der Menüzeile auf “Ansicht” klicken und dann “Werkzeugkasten” auswählen. Es öffnet sich daraufhin ein Fenster mit einer Auswahl an Formelementen, die mit einem Doppelklick auf das jeweilige Objekt in die App eingefügt werden können. In der Regel möchten wir nun auch gerne sehen, wie unsere Button später in der App aussehen wird. Um die App anzuzeigen, klicken wir im oberen Menü auf “Lokaler Computer”, woraufhin ein (schwarzes) Fenster mit einem weißen durchkreuzten Rechteck angezeigt wird – der Splashscreen – und kurze Zeit darauf unsere home.html-Seite erscheint, die in etwa so aussieht: Um die App zu schließen und zu Visual Studio zurückzukehren, fahren wir entweder mit der Maus auf die obere Kante und ziehen die App mit gedrückter Maustaste nach unten oder brechen die Ausführung mit Alt+F4 ab. Wenn wir in Visual Studio zurückkehren, sehen wir anhand des roten Balkens am unteren Bildschirmrand, dass das Debugging noch läuft. Um dies zu beenden wählen wir entweder den Shortcut Shift+F5 oder klicken im oberen Menü auf “Debugging beenden” Im nächsten Schritt fügen wir nun den Event-Listener hinzu. Hierbei handelt es sich um Steuerungslogik und diese wird in Javascript-files definiert. Wir wechseln daher in home.js und fügen in der ready-Funktion folgenden Code hinzu: 1: var button1 = document.getElementById("beispielbutton1"); 2: button1.addEventListener("click", buttonClick, false); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } In Zeile 1 greifen wir mittels document.getElementById() auf unseren Button zu und speichern das so erhaltene button-Objekt in der Variable button1. In Zeile 2 fügen wir unserem Button aus der home.html-Datei einen Event-Listener hinzu: Im ersten Argument dieser Funktion definieren wir, auf welches Event wir achten: “click”, also ein Mausklick bzw. ein Fingertab bei Touchscreens. Das zweite Argument gibt an, welche Funktion bei einem Klick auf den Button ausgeführt werden soll: “buttonClick” – diese Funktion müssen wir noch definieren. Im dritte Argument wird definiert, ob “capture” aktiviert werden soll (für dieses Beispiel nicht notwendig, daher false). Wir haben nun definiert, dass mit einem Klick auf den Button mit der ID “beispielbutton1” die Funktion “buttonClick” aufgerufen werden soll. Diese Funktion müssen wir nun ebenfalls im home.js-file definieren. Unser Datei home.js sieht damit insgesamt wie folgt aus: 1: (function () { 2: "use strict"; 3: 4: WinJS.UI.Pages.define("/pages/home/home.html", { 5: ready: function (element, options) { 6: var button1 = document.getElementById("beispielbutton1"); 7: button1.addEventListener("click", buttonClick, false); 8: } 9: }); 10:   11: function buttonClick() { 12: console.log("Auf Button geklickt"); 13: } 14:   15: })(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } In Zeile 12 definieren wir, dass der Text “Auf Button geklickt” in die Javascript-Konsole geschrieben werden soll. Wenn wir nun die App starten und einige Male auf den Button klicken, die App danach schließen und zurück in Visual Studio wechseln, sollte in unserer Konsole nun entsprechend oft der Text angezeigt werden: Wer bereits öfter in Javascript entwickelt hat, hat vielleicht des Öfteren die alert()-Funktion zum Debuggen verwendet. Das ist zwar eine relativ unschöne Methode, ist für schnelles Auffinden von Fehlern im laufenden Betrieb dennoch manchmal sinnvoll. In Windows 8 gibt es die alert()-Funktion nicht, wir können und diese jedoch sehr schnell selbst basteln, indem wir unterhalb der buttonClick-Funktion folgenden Code einfügen: 1: function alert(text) { 2: var messagedialogpopup = new Windows.UI.Popups.MessageDialog(text, "Überschrift"); 3: messagedialogpopup.showAsync(); 4: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Wir ersetzen nun den console-Eintrag in der buttonClick-Funktion durch einen Aufruf der alert()-Funktion sodass die gesamte home.js-Datei wie folgt aussieht: 1: (function () { 2: "use strict"; 3: 4: WinJS.UI.Pages.define("/pages/home/home.html", { 5: ready: function (element, options) { 6: var button1 = document.getElementById("beispielbutton1"); 7: button1.addEventListener("click", buttonClick, false); 8: } 9: }); 10:   11: function buttonClick() { 12: alert("Auf Button geklickt"); 13: } 14:   15: function alert(text) { 16: var messagedialogpopup = new Windows.UI.Popups.MessageDialog(text, "Überschrift"); 17: messagedialogpopup.showAsync(); 18: } 19:   20: })(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Wenn wir nun die App starten und auf den Button klicken, erscheint ein MessageDialog. Wir müssen nun nicht zurück in Visual Studio wechseln, wenn wir uns zB die aktuelle Variablenbelegung ansehen wollen, sondern können uns alle möglichen Infos direkt in der App anzeigen lassen: Navigation und Seiten Bisher haben wir alle Aktionen auf unserer home-Seite ausgeführt ohne diese zu verlassen. Bei größeren Projekten ist es rein aus strukturellen Gründen besser, mehrere Seiten anzulegen, zwischen denen der User navigieren kann. Das Windows 8 Framework, allen voran WinJS nimmt uns auch hier wieder einen großen Teil der Arbeit ab, unter anderem müssen wir uns nicht um das Erscheinen bzw. das Layout eines “Zurück”-Buttons kümmern, wenn wir zu einer Unterseite navigieren – dies wird ganz automatisch eingefügt (und kann natürlich auch gelöscht werden, wenn wir der Meinung sind, keinen solchen Button zu benötigen). Wir erweitern die bisher geschriebene App nun so, dass wir mit einem Klick auf unseren Button, der sich bekanntlich auf der “home”-Seite befindet, auf eine “detail”-Seite wechseln. Dazu klicken wir mit der rechten Maustaste auf unseren “pages”-Ordner, wählen “Hinzufügen” > “Neuer Ordner” und nennen diesen “detail”: Wir klicken nun mit der rechten Maustaste auf den soeben erstellten “detail” Ordner, wählen wieder “Hinzufügen” und “Neues Element”. In der nun erscheinenden Liste wählen wir “Seitensteuerelement” und im Textfeld “Namen” geben wir “detail” ein: Visual Studio fügt nun in unserem detail-Ordner die Dateien detail.html, detail.css und detail.js hinzu. Diese dreigeteilte Struktur kommt uns bereits bekannt vor, es ist wenig überraschend das selbe Prinzip wie auf unserer “home”-Seite, wenngleich der Code nicht exakt der selbe ist. Wir wechseln nun in unsere home.js-Datei, löschen die dort befindliche buttonClick-Funktion und ersetzen sie mit folgendem Code: 1: function buttonClick(eventInfo) { 2: WinJS.Navigation.navigate("/pages/detail/detail.html"); 3: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } In Zeile 2 greifen wir auf unsere altbekannte WinJS-library zurück und rufen die Funktion navigate() auf, die uns zur Verfügung gestellt wird, um bei einem Klick auf den Button in home.html zu detail.html zu navigieren. In unsere detail.html schreiben wir noch ein Rezept für einen lecker schmeckenden flockigen Becherkuchen, der ebenso schnell und einfach zu machen ist, wie unsere App. Hier der Quellcode der gesamten detail.html-Datei: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta charset="utf-8" /> <title>detail</title>   <!-- WinJS-Verweise --> <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" /> <script src="//Microsoft.WinJS.1.0/js/base.js"></script> <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>   <link href="detail.css" rel="stylesheet" /> <script src="detail.js"></script> </head> <body> <div class="detail fragment"> <header aria-label="Header content" role="banner"> <button class="win-backbutton" aria-label="Back" disabled type="button"> </button> <h1 class="titlearea win-type-ellipsis"> <span class="pagetitle">Becherkuchen Rezept</span> <span style="font-size:20px;">von Christine Hudetz</span> </h1> </header> <section aria-label="Main content" role="main">   Um einen flockigen Becherkuchen zaubern zu können benötigt man: Erst einmal die unersetzlichen Grundzutaten:<p> <li> 1 Becher Joghurt/Sauerrahm/Schlagobers (letzerer ist am flockigsten) <li> 1 Becher (ja, den Joghurt/Sauerrahm/Schlagobersbecher) Mehl (am besten „Universal“) <li> 1 Becher (noch immer derselbe) Zucker <li> ½ (!) Becher Öl <li> 1 Packerl Backpulver <li> 3 Eier <p> Hat man diese flotten Essenzen nun alle (egal in welcher Reihenfolge) in eine Schüssel zusammenpurzeln lassen, darf man seiner Fantasie freien Lauf lassen und hinzufügen, wozu man grade Lust und Laune hat. <p> Im klassischen Flockkuchen befindet sich (mind.) 1 Becher Kakao (Erfahrene Flockbäcker schütten den Kakao einfach nach Gefühl in die Schüssel – ein einziger Becher erscheint alteingesessenen Flockkennern meist etwas banal) Eine weitere klassische Zutat sind geriebene Nüsse – egal welcher Sorte – sie geben dem Becherkuchen ein noch flockigeres Geschmacksspektrum. Für einen wohltuenden Schokolade-Schock empfiehlt sich jedoch die reine Kakao-Variante. <p> Weitere typische Zutaten wären:<br> <li> ganze Nüsse <li> Schokoladestücke <li> Rosinen <li> Kokosraspeln <li> Zimt (gibt dem Kuchen einen flockig weihnachtlichen Touch!) <li> Vanille(zucker)* <li> usw usf - Der Kreativität der Flockisten sind keine Grenzen gesetzt! <p> *Anm.: Eine rein mentale Zutat. Bringt geschmacklich keine merkliche Veränderung. <p> Nachdem man mit der Wahl seiner Zutaten zufrieden geworden ist und die Schüssel nach Belieben mit flockigen Substanzen bereichert hat, mixt man das Ganze bis alles gut vermischt harmonisch vor sich her döst.<br> Währenddessen kann man schon mal den Ofen auf 180° (Ober- und Unterhitze) einschalten und vorglühen lassen. Dann darf man sich ein Stück Butter krallen und damit vergnügt die Backform (Gugelhupf, Rehrücken, Tortenform,...) auskleiden. Als krönenden Abschluss bespreuselt man die ausgebutterte Form dann noch mit Semmelbröseln – möglichst ohne bröselfreie Zonen, um potentiellem Festkleben des Kuchens keine Chance zu geben und ein einwandfreies Loslösen des fertigen Kuchens zu garantieren.<br> Ist die Form nun fertig ausgebröselt füllt man sie grazil mit dem flockig-vermixten Teig. Wer jetzt noch nicht genug Spaß am Herumflocken hatte, kann noch Schokoladestückchen in die Backform plumpsen lassen. Oder Schokostreusel, oder Rosinen, oder Kokosraspeln,...<p>   Danach schiebt man die Form auf mittlerer Schiene in den Backofen und wartet ab. Solange, bis der Kuchen schön flauschig geworden ist (ca. 45-50 min. - je nachdem wie lange man den Ofen verheizen hat lassen). <br> Hat der Kuchen die perfekte Konsistenz erreicht, holt man ihn aus dem Backrohr und stülpt ihn aus der Form. Ambitionierte Einbutterer und Ausstreusler können sich nun sicher über ein einwandfreies Ergebnis freuen. Faulere Individuen werden mit kleinen Verlusten zu rechnen haben. <p> Der fertiggebackene Kuchen kann nun beliebig mit Staubzucker, Streusel oder (für den Extra-Schoko-Flash) Schokoladeüberguss dekoriert werden. <p> Dines flockiger Becherkuchen eignet sich selbstverständlich auch perfekt für Geburtstags- und Hochzeitstorten – ein wahres Universalrezept also. <p> Viel Spaß beim Nachflocken, wünscht Dine.   </section> </div> </body> </html> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Wenn wir nun mit dem Shortcut F5 die App starten und auf den Button klicken, sollten wir auf unsere detail.html Seite gelangen, auf der sich nun unser Rezept befindet. Automatisch angelegt wurde neben der Überschrift auch ein “Zurück”-Button. Auffällig ist hierbei, dass – je nach Auflösung – der Text abgeschnitten ist und ein langweiliger schwarzer Hintergrund sowie ein einfacher Button niemanden vom Hocker haut. In einem letzten Schritt wagen wir uns jetzt an das Design, um unserer App ein bisschen Leben einzuhauchen. Pimp your site with CSS Wir wollen in diesem Abschnitt unserer App ein Hintergrundbild verpassen sowie den Button auf der home-Seite durch ein Vorschaubild mit Text ersetzen. Kümmern wir uns zunächst um das Hintergrundbild. In diesem Beispiel soll für jede Seite das gleiche Bild verwendet werden, wir müssen daher unsere default.css Datei anpassen, die sich im Ordner css befindet. Hier fügen wir ganz am Ende des default.css-files folgenden Eintrag hinzu: 1: body { 2: background-image:url(/images/background.png); 3: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Damit wird für den <body>-Tag das Hintergrundbild background.png definiert, das im Ordner images liegt. Nur: Noch liegt im Ordner images kein solches Bild. Wenn wir einen Blick in images werfen, werden wir dort einige Bilder vorfinden, es handelt sich dabei um verschiedene Logos, die wir uns ebenfalls noch ansehen werden. Zuvor aber suchen wir uns ein nettes Bild mit ausreichend guter Auflösung und ziehen dieses einfach mit gedrückter Maustaste in unseren image-Ordner: Wenn wir die App starten sollte nun bereits unser Hintergrundbild auf allen Seiten angezeigt werden. Passen wir nun im nächsten Schritt auch den Button an. Dazu wechseln wir in unsere home.html-Datei und ersetzen den Button, den wir angelegt haben mit folgendem Code: <div id="beispielbutton1" class="ManipulationElement" style="-ms-grid-column: 2"> <img alt="Cliff" src="/images/becherkuchen.jpg" style="width:250px;height:250px;"/> <div class="overlay"> <h2>Becherkuchen</h2> <p>von Christine Hudetz</p> </div> </div> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Hier passiert nicht viel Magisches: Wir definieren lediglich einen <div>-Bereich, weisen diesem die ID zu, die zuvor unser Button hatte und definieren eine class-property die wir sogleich benötigen, um das Element in CSS stylen zu können. Innerhalb des <div> liegt ein Bild, das in der src auf ein Bild eines Becherkuchens verweist, das wir ebenso wie das Hintergrundbild in den images-Ordner ziehen müssen. Zuletzt folgt ein weiterer <div>-Tag, in dem Text definiert wird, der später halbtransparent am Bild erscheinen soll. Wechseln wir nun in die home.css Datei und fügen folgenden Code am Ende hinzu: .ManipulationElement { position: relative; display: -ms-grid; -ms-grid-columns: 1fr; -ms-grid-rows: 1fr; height: 250px; width: 250px; top: 50px; }   .ManipulationElement .overlay { position: relative; -ms-grid-row-align: end; background-color: rgba(0,0,0,0.65); height: 50px; padding: 15px 15px; overflow: hidden; -ms-grid-column: 1; } .ManipulationElement .overlay h2, .ManipulationElement .overlay p { color: rgba(255, 255, 255, 0.8); margin: 0px; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Hier wird im wesentlichen die Klasse “ManipulationElement” definiert, die unserem <div> in der home.html bestimmte Styles hinzufügt. Wenn wir nun die App starten, sieht die App – natürlich abhängig von den verwendeten Bildern – etwa wie folgt aus: Im letzten Schritt soll nun der Text auf der detail.html-Seite, der abgeschnitten ist, sichtbar gemacht werden. Dazu verwenden wir eine schnelle, einfache (und unsaubere) Lösung und ersetzen in Zeile 17 den Code <div class="detail fragment"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } durch <div class="detail fragment" style="overflow:scroll;"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Dadurch werden der Seite einfach Scrollbars hinzugefügt. Wenn wir nun eine Rezeptesammlung mit vielen Rezepten bauen wollen, freut es viele sicher zu lesen, dass es schon fertige Vorlagen gibt, mit denen Apps im Stil einer Grid – so wie wir sie jetzt händisch Stück für Stück gebaut haben – schnell erstellt werden können. Wir klicken dazu im Menü oben auf “Datei” > “Neu” > “Projekt” und wählen “Raster-App” aus. Wenn wir diese App mit F5 starten, sieht sie so aus: Die grauen Quadrate sind Bilder, die im Ordner images liegen und können natürlich nun im Fall einer Rezepte-App einfach durch eigene Bilder von Speisen und Kuchen ersetzt werden. Alle Daten der App werden übrigens im Ordner js im file data.js definiert. Zuletzt passen wir noch die Logos an, damit auch unser SplashScreen hübscher wird. Wenn wir auf das Logo splashscreen.png doppelklicken, öffnet sich der in Visual Studio integrierte Grafik-Editor. Hier können einfache Änderungen an der Bildern vorgenommen werden. Mit etwas Motivation lässt sich schnell ein Kuchen-Icon basteln, das ganz im Stil der Standard-Win8-Tiles schlicht und weiß gehalten sein soll. Die Farbe des SplashScreens lässt sich mit einem Doppelklick auf package.appxmanifest in der Zeile “Hintergrundfarbe” ändern. Das für den SplashScreen erstellt Logo, können wir nun auch für die anderen Logos verwenden.  Die weiteren Schritte Wenn wir eine App erstellt haben, möchten wir diese in der Regel auch einem breiten Publikum vorstellen und sie im Windows Store veröffentlichen. Um dies zu bewerkstelligen, navigiere man zunächst auf die Registrierungs-Seite des Windows Dev-Centers. Nach einem klick auf “Jetzt registrieren” können sich Besitzer eines Windows-Accounts einloggen oder neue User mit einem Klick auf “Weiter” in der linken Spalte registrieren. Für die Registrierung ist neben der Angaben von persönlichen Daten auch eine Kreditkarte erforderlich. Für Studenten ist (im Rahmen des DreamSpark Programms) die Mitgliedschaft kostenlos. Ist der Account angelegt und die App fertig, steht der Veröffentlichung nichts mehr im Wege. In diesem Blogeintragfindet sich eine Schritt-für-Schritt-Anleitung, um die App in den Store zu bekommen und typische Fehler zu vermeiden. Ressourcen Windows Dev-Camp: Entwickeln von Windows Store Apps Windows 8 Frameworks Datenschutzrichtlinien für Windows Store Apps

Windows 8 App Frameworks

Von Georg Binder Autor Feed 11. March 2013 11:03
Die erste App und das Kennenlernen des Stores sind… gewöhnungsbedürftig. Um es zu erleichtern kann man mal eine Open Source App nehmen und mit dieser seine ersten Erfahrungen machen. [More]

Developer Events

Von Georg Binder Autor Feed 10. March 2013 14:43
Interesse an Apps für Windows 8, Windows Phone und Azure? Eine Serie von Events (Camps, Hackathons) bieten die Möglichkeit dazu, Frühling, Sommer, Herbst und Winter sinnvoller zu verbringen, als am z.B. am Strand zu sitzen und ein Buch zu lesen. [More]

Warum Windows Store Apps für Web-Entwickler interessant sind

Von Rina Ahmed Autor Feed 19. February 2013 15:59
Mit der Einführung von Windows 8 haben Web-Entwickler erstmals die Möglichkeit, Apps für den Windows Store mit den ihnen bekannten Webtechnologien HTML/CSS und JavaScript zu entwickeln. Hierbei muss man sagen, dass Microsoft diese Technologien nicht einfach nur halbherzig unterstützt, sondern wie in Abbildung 1 ersichtlich ist, diese eine gleichwertige Alternative zu den bereits bekannten .Net Sprachen darstellen. Abb. 1 Das heißt also, dass ich eine Windows Store App entwickeln kann, indem ich meine Businesslogik in JavaScript schreibe und mein Frontend wie gewohnt in HTML und mit CSS baue. Der große Vorteil hier ist aber, dass ich mittels der WinRT APIs auch Zugang zu gerätespezifischen Features habe, wie zum Beispiel Geolocation. Für Webentwickler ist das eine ganz spannende Sache, weil sich neue Möglichkeiten für tolle Apps ergeben. Den Beweis, dass man super Windows Store Apps in JavaScript schreiben kann, liefert gleich Microsoft selbst. Die Standard Windows 8 Apps, die auf jedem Windows 8 Gerät bereits von Haus aus installiert sind, wurden gänzlich oder teilweise in JavaScript geschrieben. Wenn man sich diese Apps, wie zum Beispiel Wetter, Finanzen und Nachrichten anschaut, so sehen wir, dass diese Apps nicht nur schön aussehen, sondern vollwertig in die Windows 8 User Experience integriert sind. Microsoft hat damit einen wesentlichen Schritt in Richtung Unterstützung von Standards getan und führt mit gutem Beispiel. Um nun tolle Windows 8 Apps mittels JavaScript zu schreiben, wird von Microsoft die Windows Library for JavaScript (WinJS) bereitgestellt. Diese Library bietet dem Entwickler APIs, um einerseits das Look and Feel von Windows 8 Apps zu gewährleisten, andererseits können viele spezifische Merkmale von Windows Store Apps, wie Touch Support, Application Management, Charms und Navigation leicht implementiert werden. Webentwickler, die auf offene Standards besonders großen Wert legen, denken sich vielleicht nun, warum sie Windows Store Apps schreiben sollten, wenn sie erst recht wieder die proprietäre Library von Microsoft verwenden sollen. Dazu muss man sagen, dass es nicht verpflichtend ist, diese Library zu verwenden. Man kann sehr wohl, alles selbst schreiben. Aber um in den Windows Store zu kommen, ist es erforderlich gewisse Windows 8 Funktionalitäten zu unterstützen und es kann mitunter viel Code sein, wenn man alles selbst schreiben will. Kurz gesagt, die WinJS Library vereinfacht es, hochqualitative Apps mit der Windows 8 User Experience zu schreiben. Es gibt auch einige wesentliche Gründe, warum Web-Entwickler sich Windows Store Apps genauer ansehen sollten. Bekanntheit Bis auf die bereits erwähnte WinRT und WinJS APIs unterstützt Microsoft den Standard in HTML5, CSS3 und JavaScript. Alles, was ihr über diese Technologien gelernt haben, könnt ihr für Windows Store Apps verwenden. Das Schreiben von Apps für den Windows Store fühlt sich so an, als ob ihr auch für das Web wie bisher entwickelt habt. Natürlich muss man etwas dazulernen, aber die Menge hält sich in Grenzen. Man kann ziemlich schnell beginnen an einer App zu schreiben. Spannend ist besonders, dass Webentwickler nun auch die Möglichkeit haben auf gerätespezifische Merkmale wie Geolocation, Accelerometer durch die WinRT APIs zuzugreifen, was früher nur Desktopentwicklern vorbehalten war. Portabilität Der klare Vorteil bei der Verwendung von Webtechnologien wie HTML und JavaScript ist natürlich, dass diese über verschiedene Plattformen hinweg laufen. Dass Microsoft jetzt eine Unterstützung für HTML5 und Javascript bietet, lässt den Windows Store als eine weitere Option für Entwickler erscheinen, die Apps für mehrere Plattformen schreiben wollen. Klar, man soll sich bei den verschiedenen Plattformen an die jeweiligen Designrichtlinien halten. Aber wenn man bei den Windows Store Apps die WinJS und WinRT API calls entfernt, so kann man sicher sein, dass der restliche JavaScript Code überall problemlos läuft, wo JavaScript unterstützt wird. Microsofts Anstrengungen, offene Standards zu unterstützen, gehen so weit, dass sie Änderungen im Standard, die es zur Zeit des ersten Windows 8 Preview noch nicht gaben, im Nachhinein noch im nächsten Preview eingebaut haben. Das gibt dem Entwickler die Sicherheit, dass sein den Standards entsprechend geschriebener Code auch überall läuft und, dass Microsoft nicht vorhat, Entwickler fest an Windows zu ketten. Reichweite Es steht außer Frage, dass Windows das meist verbreitete Betriebssystem ist. Die Apps, die Webentwickler schreiben, stehen nun zusätzlich allen Benutzern im Windows Store zur Verfügung. Bereits in den ersten zwei Monaten wurden 60 Millionen Windows 8 Lizenzen weltweit verkauft. Hier bildet sich für den Webentwickler eine große Chance, seine Apps mit einer riesigen Benutzergruppe zu teilen und sein Talent zur Schau zu stellen. Natürlich kann das auch eine lukrative Möglichkeit sein, mehr Benutzern die App zum Kauf anzubieten. Wenn ihr bereits mit Webtechnologien gearbeitet habt, so könnt ihr also mit einer kleinen Lernkurve bald eigene App für den Windows Store schreiben. Ich hoffe, dass euch die obigen Gründe, Windows Store Apps schmackhaft gemacht haben und probiert mal selbst aus, wie ihr ganz ohne .Net supertolle Apps für Windows 8 entwickeln könnt. Ressourcen: Windows 8 Store Apps Why Front-End Developers Should Build Apps for Windows 8 Building the Bing apps for Windows 8

Windows 8 App mit Backend in der Cloud – Windows Azure Mobile Services

Von Rina Ahmed Autor Feed 10. February 2013 11:26
Wenn man eine Windows 8 App schreibt und persistente Daten zum Speichern hat, stellt sich über kurz oder lang die Frage, welche Backend-Lösung man für die Daten verwenden will. Windows Azure Mobile Services bieten hierbei eine einfache Lösung, um eine Datenbank in der Cloud für Windows 8 Apps zu nutzen. In diesem Tutorial will ich anhand einer einfachen Windows 8 App, die Artikel in einer Einkaufsliste speichert, zeigen, wie man auf die Schnelle die Datenbank erstellen und für die App verwenden kann. Folgende Schritte werden wir durchgehen: Vorbereitung Einrichten eines Windows Azure Mobile Services Erstellen einer Tabelle Eine einfache Windows 8 App schreiben Direkter Zugriff auf die Datenbank in Visual Studio Vorbereitung Wir benötigen für unsere App Visual Studio und Windows Azure SDK. Falls ihr es noch nicht installiert habt, könnt ihr hier Visual Studio Express 2012 und Windows Azure SDK herunterladen. Um die Services von Windows Azure in Anspruch zu nehmen, ist auch Windows Azure Konto notwendig. Hier kann man sich für ein 90-Tage gratis Trial anmelden. Jetzt müssen wir die Mobile Services in unserem Azure Account noch aktivieren. Geht auf die Seite https://account.windowsazure.com und loggt euch mit eurer Live Id ein. Ihr klickt dann auf den Punkt Vorschaufeatures. Auf der Seite der Vorschaufeatures aktivieren wir die Mobile Services mittels Try it now. Einrichten eines Windows Azure Mobile Services Nachdem wir nun die Grundvoraussetzungen erfüllt haben, können wir mit unserer App beginnen. Wir wollen eine einfache Einkaufsliste entwickeln, in der wir Artikel eingeben können, die dann in einer Datenbank mittels Windows Azure Mobile Services gespeichert werden. So richten wir unser Windows Azure Mobile Service ein: Zuerst müssen wir uns im Windows Azure Management Portal unter http://manage.windowsazure.com mit der Live Id anmelden. In der unteren Leiste klickt Ihr auf Neu.   Danach wählt Ihr den Punkt Mobiler Service und klickt auf Erstellen. In dem Dialogfeld müsst Ihr einen Namen für das Mobile Service auswählen, der Teil der URL sein wird. Das heißt, wenn der Name bereits vergeben ist, müsst Ihr einen ähnlichen Namen wählen. Danach wählt ihr Eine neue SQL-Datenbankinstanz erstellen und North Europe als Region und klickt auf den Pfeil unten. Im zweiten Schritt wählt ihr unter Server den Punkt Neuer SQL-Datenbankserver und gebt ein Username und Passwort an. Wichtig: merkt euch den Username und das Passwort, da ihr denselben Datenbankserver für weitere Mobile Services verwenden könnt. Falls ihr bereits einen Datenbankserver erstellt habt, dann wählt ihr unter Server diesen aus und gebt eure Anmelde-Daten für den Server an. Ihr habt jetzt ein Mobile Service erstellt, dass ihr ansprechen könnt. Bevor wir uns der App widmen, müssen wir noch eine Tabelle in unserer Datenbank erstellen. Erstellen einer Tabelle In unserem Management Portal gehen wir auf Mobile Services und wählen das gerade von uns erstellte Mobile Service aus. Dort klicken wir auf Daten in der oberen Leiste. Danach gehen wir auf Eine Tabelle hinzufügen. Da wir in unserer Einkaufsliste Artikel speichern wollen, benötigen wir eine Tabelle namens Artikel. Nun haben wir in unserem Mobile Service die Tabelle für unsere Artikel Objekte erstellt. Wenn wir auf unsere Tabelle jetzt klicken und auf Spalten gehen, sehen wir, dass diese Tabelle bereits eine Spalte namens Id besitzt. Eine einfache Windows 8 App schreiben Zunächst erstellen wir uns ein neues Projekt in Visual Studio unter Datei/Neu… . Wir wählen die Kategorie Windows Store unter C# nehmen die Leere App und geben MeineEinkaufsliste als Namen an. Links im Solution Explorer klicken wir mit rechter Maustaste auf References und dann auf Add reference. Unter Extensions klicken wir Windows Azure Mobile Services Managed Client an (Das setzt voraus, dass wir in der Vorbereitungsphase Windows Azure SDK installiert haben). Im Solution Explorer auf der rechten Seite können wir alle Dateien in unserem Projekt sehen. Wir öffnen durch Doppelklick die Dateien App.xaml.cs und MainPage.xaml.cs und fügen in beiden Dateien oben folgendes Statement ein: using Microsoft.WindowsAzure.MobileServices; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } In App.xaml.cs fügen wir folgenden Code gleich über dem Konstruktor der Klasse App hinzu: public static MobileServiceClient MobileService = new MobileServiceClient( "https://meineeinkaufsliste.azure-mobile.net/", "jdJuIxpihCodEilnMsCVIFORiMHuXm99" ); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Wir stellen hier eine Instanz für den MobileServiceClient bereit, wobei wir dem Konstruktor, die URL des Mobile Services und den Anwendungsschlüssel als Parameter übergeben. Diese zwei Werte müsst Ihr gemäß eurer App ersetzen. Die Werte findet Ihr, wenn Ihr im Azure Management Portal unter Mobile Services auf euer Mobile Service geht und oben Dashboard wählt. In der rechten Spalte befindet sich die URL des Mobile Services und in der unteren Leiste im Punkt Schlüssel Verwalten könnt ihr den Anwendungsschlüssel rauskopieren. In der Datei MainPage.xaml.cs schreiben wir eine Klasse für unsere Artikel Objekte. Ihr könnt den Code direkt oberhalb der MainPage Klasse einfügen. public class Artikel { public int Id { get; set; }   [DataMember(Name = "bezeichnung")] public string Bezeichnung { get; set; }   [DataMember(Name = "gekauft")] public bool Gekauft { get; set; } } Und dann fügen wir noch folgendes Statement oben im using Block hinzu: using System.Runtime.Serialization; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Wir haben nun eine Klasse Artikel geschrieben, die eine Variable Bezeichnung für den Namen des Artikels und eine Variable Gekauft besitzt, um anzugeben, ob der Artikel noch ausständig ist oder bereits gekauft. Durch [DataMember(Name=”bezeichnung”)] haben wir sichergestellt, dass die Klassenvariable Bezeichnung einer Spalte in der Tabelle Artikel entspricht. Unsere Tabelle Artikel in unserem Mobile Service besitzt ein Dynamisches Schema. Wenn wir ein Artikel-Objekt an das Mobile Service schicken, werden automatisch die Spalten generiert. In der Klasse MainPage fügen wir folgende Variablen oberhalb dem MainPage()-Konstruktor: private MobileServiceCollectionView<Artikel> artikel; private IMobileServiceTable<Artikel> artikelTable = App.MobileService.GetTable<Artikel>(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }Hier stellen wir eine Instanz der Tabelle aus unserem MobileService als artikelTable bereit und definieren eine Collection für unsere Artikel Objekte, die wir aus der Tabelle einlesen wollen. Dann fügen wir noch folgende Methoden in der Klasse hinzu. private async void InsertArtikel(Artikel art) { await artikelTable.InsertAsync(art); artikel.Add(art); }   private async void UpdateCheckedArtikel(Artikel art) { await artikelTable.UpdateAsync(art); artikel.Remove(art); }   private void RefreshArtikel() { artikel = artikelTable .Where(art => art.Gekauft == false) .ToCollectionView(); //Artikelliste.ItemsSource = artikel; } InsertArtikel und UpdateCheckedArtikel fügen das als Parameter übergebene Artikel Objekt in die Tabelle in unserem MobileService ein bzw ändern die Daten in der Update Methode. In der RefreshArtikel Methode lesen wir alle Artikel, die noch nicht gekauft wurden, aus der Tabelle in unsere Collection artikel. Wir wollen, dass diese Methode aufgerufen wird, sobald der User auf die Seite kommt, daher machen wir den Methodenaufruf in der OnNavigatedTo-Methode, die in der Vorlage bereits bereitgestellt wird. protected override void OnNavigatedTo(NavigationEventArgs e) { RefreshArtikel(); } Jetzt fügen wir noch zwei EventHandler-Methoden in der Klasse hinzu. private void SaveButton_Click(object sender, RoutedEventArgs e) { //Artikel art = new Artikel //{ Bezeichnung = Artikelbezeichnung.Text};   //InsertArtikel(art); }   private void CheckBoxComplete_Checked(object sender, RoutedEventArgs e) { CheckBox cb = (CheckBox)sender; Artikel art = cb.DataContext as Artikel; UpdateCheckedArtikel(art); } In der SaveButton_Click-Methode behandeln wir das Ereignis, in dem ein Benutzer auf den Speichern Button klickt, nachdem er einen neuen Artikel eingegeben hat. Wir erstellen ein neues Artikel-Objekt und rufen die InsertArtikel-Methode zum Einfügen in die Tabelle auf. Da wir das User Interface noch nicht erstellt haben, kommentieren wir den Code aus, nachdem wir die Controls in der MainPage.xaml definiert haben. In der CheckBoxComplete_Checked-Methode behandeln wir das Ereignis, in dem ein Benutzer die Checkbox anklickt, um anzudeuten, dass der Artikel gekauft wurde. Hier rufen wir die UpdateCheckedArtikel-Methode auf. Wir gehen nun zu der Datei MainPage.xaml und  ersetzen das Grid-Element mit folgendem Code: <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="80"/> <ColumnDefinition Width="400"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="120"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock Grid.Column="1" Text="Einkaufsliste" Style="{StaticResource PageHeaderTextStyle}" Margin="0"/> <StackPanel Grid.Column="1" Grid.Row="2" Margin="0,50,0,0"> <TextBlock Text="Artikelbezeichnung:" Style="{StaticResource BasicTextStyle}"/> <TextBox x:Name="Artikelbezeichnung" Width="250" Height="30" HorizontalAlignment="Left"/> <Button Content="Speichern" Margin="0,10,0,0" Click="SaveButton_Click" /> </StackPanel>   <StackPanel Grid.Column="2" Grid.Row="2"> <TextBlock Text="Meine Artikel:" Margin="0,0,0,20" Style="{StaticResource BasicTextStyle}"/> <ListView x:Name="Artikelliste"> <ListView.ItemTemplate> <DataTemplate> <StackPanel> <CheckBox Name="CBgekauft" IsChecked="{Binding Gekauft, Mode=TwoWay}" Checked="CheckBoxComplete_Checked" Content="{Binding Bezeichnung}" /> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackPanel> </Grid> Jetzt fehlt noch das Auskommentieren des Codes in der SaveButton_Click-Methode in MainPage.xaml.cs, sowie das Auskommentieren der letzten Zeile (Artikelliste.ItemsSource = artikel; ) in der RefreshArtikel-Methode. Als letzten Punkt wollen wir noch den Look der App auf das helle Farbschema ändern. Dazu gehen wir in die App.xaml Datei und fügen im Application-Element das Attribut RequestedTheme mit dem Wert Light ein. Das Ganze sieht dann so aus: <Application x:Class="MeineEinkaufsliste.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MeineEinkaufsliste" RequestedTheme="Light"> Nun können wir unsere App ausprobieren. Wenn ihr in Visual Studio F5 drückt, dann wird die App kompiliert und gestartet. Ihr könnt im linken Teil Artikelbezeichnungen eingeben, die in die Datenbank mittels Mobile Service eingefügt werden und im rechten Teil werden die aus der Datenbank ausgelesenen Artikel angezeigt. Bei der Abfrage nach der Artikel werden nur jene angezeigt, die den Wert false in der Gekauft Spalte haben. Der Wert false wird dann auf der Seite mit einer leeren Checkbox dargestellt.  Direkter Zugriff auf die Datenbank in Visual Studio Wir haben bereits ein Mobile Service mit einer Datenbankinstanz eingerichtet und eine Tabelle erstellt. Weiters haben wir das aus den Eingabewerten erstellte Artikel Objekt in die Tabelle eingefügt und aus der Tabelle anhand der Spalte Gekauft selektiert ausgelesen. Wir haben also eine funktionierende Backend-Lösung, ohne eine einzige Zeile SQL geschrieben zu haben! Es kann aber Fälle geben, in denen es praktischer ist, die Datenmanipulation direkt mit SQL zu erledigen als über eine grafische Oberfläche. Wenn wir beispielsweise eine weitere Spalte namens Menge in unserer Tabelle hinzufügen wollen, genügt es in unserer Klasse Artikel in MainPage.xaml.cs ein weitere Klassenvariable (als DataMember deklariert) namens Menge hinzuzufügen und im Interface Felder für das Einlesen und Ausgeben der neuen Information vorzusehen. Wegen des dynamischen Schema wird beim nächsten Einfügen eines Artikels mit Mengenangabe automatisch eine weitere Spalte in der Tabelle hinzugefügt. Alle unsere bisherigen Daten werden allerdings Null-Werte in der neuen Spalte haben. Wenn wir sinnvollere Werte für die Spalte Menge in den bisherigen Artikel Datensätzen haben wollen, ist es am schnellsten, dies mit einem UPDATE Statement in SQL zu realisieren. Dieses Szenario wollen wir nun durchspielen, damit wir sehen können, wie wir direkt auf die Datenbank unseres Azure Mobile Services zugreifen und SQL Code ausführen können. Als erstes ändern wir die Artikelklasse in MainPage.xaml.cs und fügen eine weitere Klassenvariable Menge ein, sodass unsere Artikelklasse so aussieht: public class Artikel { public int Id { get; set; }   [DataMember(Name = "bezeichnung")] public string Bezeichnung { get; set; }   [DataMember(Name = "gekauft")] public bool Gekauft { get; set; }   [DataMember(Name = "menge")] public string Menge { get; set; } } Danach ändern wir die Methode für das Event des Buttonklicks beim Speichern. Wir wollen bei der unserem neuen Artikel Objekt, die vom Benutzer angegebene Menge miteinberücksichtigen. Unsere SaveButton_Click Methode sieht daher so aus: private void SaveButton_Click(object sender, RoutedEventArgs e) { Artikel art = new Artikel { Bezeichnung = Artikelbezeichnung.Text, Menge = Menge.Text};   InsertArtikel(art); } Nun fügen wir in der MainPage.xaml unmittelbar über die Definition für den Speichern Button die Zeilen, um ein Eingabefeld für die Artikelmenge zu erstellen. <TextBlock Text="Menge:" Style="{StaticResource BasicTextStyle}" Margin="0,15,0,0"/> <TextBox x:Name="Menge" Width="50" Height="30" HorizontalAlignment="Left"/> Gleich nach dem CheckBox Element in unserer ListView namens Artikelliste fügen wir diese Zeile ein: <TextBlock Name="Artikelmenge" Text="{Binding Menge}" Margin="27,0,0,5"/> Wenn wir jetzt unsere App starten (F5), so sehen wir dass wir jetzt Artikel mit Mengenangabe eingeben können und für alle Artikel wird die Mengenangabe anzeigt. Wenn wir jetzt auf unser Management Portal gehen und in unserer Tabelle Artikel (unter dem erstellten Mobile Services auf Daten klicken) den Tab Spalten in der oberen Leiste wählen, so sehen wir dass unsere Tabelle jetzt auch eine Spalte Menge besitzt. In unserer App sehen wir auch die neue Information der Artikelmenge. Bevor wir versuchen, auf die Datenbank direkt in Visual Studio zugreifen zu können, müssen wir noch sicherstellen, dass unsere IP als erlaubte Zugriffsquelle im Azure Management Portal gelistet ist. Zunächst wählt ihr unter Datenbanken, die DB Instanz eures Mobile Services. Dort findet ihr in der rechten Spalte den Link Zulässige IP-Adressen verwalten. Hier habt ihr nun zwei Möglichkeiten eure IP Adresse einzugeben. Entweder ihr übernimmt die vorgeschlagene IP unter Aktuelle Client-IP-Adresse, indem ihr auf den Pfeil daneben (rote Markierung) klickt oder ihr  gebt die IP bzw den IP Adressenbereich selbst ein (orange Markierung). Ich habe im Screenshot einige IP Adressen vom Screenshot entfernt, daher seht ihr dort einige leere Felder. Damit eure Eingabe übernommen wird, müsst ihr noch in der unteren Leiste auf Speichern klicken. In Visual Studio findet ihr am linken Rand den SQL Server Object Explorer. Dort klickt ihr auf das Icon, um eine neue SQL Instanz hinzuzufügen. In dem Dialogfeld gebt ihr nun den Server-Namen und die Login-Daten für eure DB ein, die ihr beim Einrichten des Mobile Services im dritten Schritt eingegeben habt. Den Server-Namen findet ihr direkt nach dem Punkt Zuständige IP-Adressen verwalten, den ihr im vorigen Schritt dieses Tutorials gesehen habt.   Jetzt wo eure Datenbank hinzugefügt ist, klicken wir im SQL Server Object Explorer auf das Icon für eine neue Query. Und dann wählen wir in der SQL Datei in der oberen Leiste im Drop Down Feld unsere Datenbankinstanz aus. Nun sind wir bereit im Fenster SQL Code zu schreiben und auszuführen. Beginnen wir mit einem einfachem SELECT Statement. Gebt im SQL Fenster den grün markierten Befehl ein. Vor dem Tabellennamen haben wir unseren Schema-Namen, der Name des Mobile Services in unserem Fall ein. Mit Strg + Shift + E können wir den Befehl ausführen oder wir klicken auf den rot markierten Pfeil. Darunter sehen wir im Ergebnisfeld unsere Ergebnisdaten, in diesem Falle alle Rows. Nun wollen wir alle Artikel, die in der Spalte Menge einen Nullwert besitzen auf einen sinnvollen Wert, beispielsweise 1, updaten. Dazu schreiben wir folgendes UPDATE Statement in das SQL Fenster und führen es wieder aus. UPDATE MeineEinkaufsliste.ArtikelSET menge = '1'WHERE menge IS NULLGO Wenn wir jetzt wieder das obige SELECT Statement aus dem vorigen Schritt ausführen, so bekommen wir das erwartete Ergebnis. Wir haben nun erfolgreich eine Windows 8 App geschrieben, die eine Backend in der Cloud hat. Wie ihr gesehen habt, ging das ganze sehr schnell und unkompliziert. Wir haben auch gesehen, wie wir die Datenbank direkt ansprechen können und unsere Daten mittels T-SQL manipulieren können. In einem späteren Teil werden wir uns anschauen, wie wir Daten validieren können, bevor wir diese in die Tabelle einfügen. Hier sind noch alle Ressourcen für dieses Tutorial aufgelistet. Ressourcen: Visual Studio Express 2012 Windows Azure SDK Windows Azure kostenlos testen Windows Azure Mobile Services Windows Store Apps Getting Started with Data in Mobile Services

Datenschutz & Cookies · Nutzungsbedingungen · Impressum · Markenzeichen
© 2013 Microsoft. Alle Rechte vorbehalten · BlogEngine.NET 2.7.0.0 · Diese Website wird für Microsoft von atwork gehostet.
powered by atwork