Dieser Artikel ist Tag #5 der Serie 8 Tage Windows Phone 8 von Geert van der Cruijsen.
Der Originalartikel befindet sich hier: 8 days of Windows Phone 8 — Day 5: .net 4.5 & C# 5.0.
Willkommen zurück zu meiner Artikelserie 8 Tage Windows Phone 8. Heute, am fünften Tag der Serie, reden wir über die neuen Features im .NET 4.5 Framework und in der Sprache C# 5.0. Diese können Ihnen dabei helfen, tolle Windows Phone Anwendungen zu bauen. Die Features, auf die wir heute besonders eingehen wollen, sind die Schlüsselwörter async und await und der DataContractJsonSerializer.
- Tag 0: Einleitung zu den 8 Tagen Windows Phone 8
- Tag 1: Überblick über das SDK
- Tag 2: Live Tiles und Sperrbildschirm
- Tag 3: Der Emulator & das Simulation Dashboard
- Tag 4: Die neuen Bildschirmauflösungen
- Tag 5: .NET 4.5 & C# 5.0
- Tag 6: Die API zur Sprachsteuerung
- Tag 7: NFC und Bluetooth
- Tag 8: Brieftasche und In-App Käufe
.NET Framework 4.5 und C# 5.0
Bei der Aktualisierung einer Anwendung von Windows Phone 7 auf Windows Phone 8 aktualisieren wir diese auch von Silverlight auf das .NET 4.5 Framework und die C# 5.0 Sprache. Damit bekommen Windows Phone Entwickler einige neue Features, die nicht wirklich Teil des SDK sind, die aber extrem nützlich für Sie als Entwickler von mobilen Anwendungen sind. Eines dieser neuen Features ist das async und await Muster. Damit wird das Bauen von asynchronen Anwendungen wesentlich vereinfacht und trägt damit indirekt zu einer reaktiven Benutzerschnittstelle für den Endnutzer bei. Das andere Thema, auf das ich heute eingehen möchte, ist die Verwendung des DataContractJsonSerializer. Diese Klasse hilft Ihnen, zwischen Objekten und JSON Strings zu serialisieren und zu deserialisieren. Das ist sehr nützlich, wenn man aus einer App auf Dienste im Web zugreift.
Unglücklicherweise verwenden (noch?) nicht alle APIs im SDK die async und await Schlüsselwörter. WebClient und HttpWebRequest verwenden dieses Feature nicht. Möglicherweise werden wir irgendwann den HttpClient wie unter Windows 8 verwenden können.
In der Beispielanwendung zum heutigen Artikel wollte ich idealerweise die Demonstration des async/await-Patterns und des JSON Serializers kombinieren. Da wir das async/await-Pattern nicht verwenden können, um eine Datei aus dem Web zu holen, laden wir einfach eine lokale Datei. Die APIs zum Zugriff auf lokale Dateien verwenden die Klasse Task und damit das async/await-Pattern. Fangen wir also an, eine sehr einfache TODO-Listen-Anwendung zu bauen.
Erstellen Sie ein neues Windows Phone 8 Projekt und fügen Sie eine Klasse ToDo hinzu. Diese werden wir zur Beschreibung eines Eintrags in der TODO-Liste verwenden. Um diese Daten später in einer JSON Datei speichern zu können, fügen wir einige Attribute hinzu, damit der DataContractJsonSerializer weiß, wie die Daten in eine JSON Datei serialisiert werden sollen. Fügen Sie das [DataContract] Attribut der ToDo Klasse hinzu und das [DataMember] Attribut allen Eigenschaften, die nach JSON serialisiert werden sollen. Standardmäßig wird der Serializer den Elementen in der JSON Datei die selben Namen geben wie die entsprechenden Eigenschaften in Ihrer Klasse. Wenn Sie möchten, dass die Elemente in der JSON Datei einen anderen Namen haben, können Sie das DataMember Attribut entsprechend verändern. Im Code unten sehen Sie dies am Beispiel der Eigenschaft Content. Das entsprechende Feld in der JSON Datei wird den Namen „Text“ haben.
[DataContract] public class ToDo { [DataMember] public string Title { get; set; } [DataMember] public DateTime Date { get; set; } [DataMember(Name="Text")] public string Content { get; set; } }
Nachdem wir jetzt einen einfachen Container für unsere Objekte haben, lassen Sie uns etwas Geschäftslogik mit dem Namen ToDoService erstellen, um die Liste der Aufgaben zu speichern und wieder aus der Datei in einem lokalen Ordner (LocalFolder) zu laden. LocalFolder ist der Wurzelordner Ihrer Anwendungsdaten — unter Windows Phone 7 war das Isolated Storage.
Als erstes fügen wir unserem ToDoService eine Methode hinzu, um die Liste der Aufgaben zu speichern.
public async Task<string> SaveToDos() { List<ToDo> todos = new List<ToDo>(); todos.Add(new ToDo(){Title="todo 1", Date = DateTime.Now, Content="finish this series of blogposts"}); todos.Add(new ToDo(){Title="todo 2", Date = DateTime.Now, Content="Pick up milk from the store"}); todos.Add(new ToDo(){Title="todo 3", Date = DateTime.Now, Content="Wash my car"}); var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(List<ToDo>)); MemoryStream ms = new MemoryStream(); dcjs.WriteObject(ms,todos); string json = Encoding.UTF8.GetString(ms.ToArray(),0,(int)ms.Length); StorageFile todoFile = await localFolder.CreateFileAsync("todos.json",CreationCollisionOption.ReplaceExisting); using (var f = await todoFile.OpenStreamForWriteAsync()) { await f.WriteAsync(ms.ToArray(),0,(int)ms.Length); f.Close(); } return json; }
Beachten Sie das async Schlüsselwort vor dem Rückgabetyp in der Methode. Damit kann die Methode asynchron aufgerufen werden und sie wird immer einen Task zurückgeben, welcher den Rückgabewert beinhaltet. In der Methode füllen wir die Liste der Aufgaben zunächst mit einigen Einträgen. Danach erstellen wir einen DataContractJsonSerializer. Dabei geben wir im Konstruktor an, welchen Typ wir serialisieren wollen. Wir verwenden dann den DataContractJsonSerializer, um die Liste der Aufgaben in eine JSON Zeichenkette zu serialisieren. Diesen geben wir am Ende der Methode zurück.
Sobald wir den JSON String haben, erstellen wir eine neue Datei im lokalen Ordner, indem wir die Methode CreateFileAsync aufrufen. Beachten Sie das await Schüsselwort im Aufruf der Methode, welcher grob bedeutet, dass der Code unterhalb des Aufrufs erst ausgeführt wird, wenn der asynchrone Aufruf abgeschlossen ist. Wenn die lokale Datei erstellt ist, schreiben wir einfach die JSON Zeichenkette in diese Datei und schließen den Stream.
Jetzt, wo wir die Aufgabenliste in die lokale Datei gespeichert haben, lassen Sie uns diese wieder lesen und am Bildschirm anzeigen. Wir implementieren hierzu in unserem ToDoService eine weitere Methode mit dem Namen GetToDos(). Diese liest die JSON Datei ein und deserialisiert diese zurück in die Liste der Aufgaben.
public async Task<List<ToDo>> GetToDos() { var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; StorageFile todoFile = await localFolder.GetFileAsync("todos.json"); DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(List<ToDo>)); var stream = await todoFile.OpenStreamForReadAsync(); var todos = dcjs.ReadObject(stream) as List<ToDo>; return todos; }
Wir beginnen wieder, indem wir uns eine Referenz auf den lokalen Ordner und auf die JSON Datei holen. Nachdem wir das StorageFile Objekt haben, erstellen wir wieder einen neuen DataContractJsonSerializer. Wir öffnen den Stream aus unserer StorageFile und übergeben diesen an den DataContractJsonSerializer, um die Daten zurück in eine Liste von Aufgaben zu deserialisieren. Damit sind wir fertig.
Um die Demo abzuschließen, fügen wir der Hauptseite eine TextBox hinzu, in welcher wir die JSON Zeichenkette darstellen. Weiterhin bauen wir ein ItemsControl ein, welches die Liste der Aufgaben anzeigt.
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <ScrollViewer> <StackPanel> <TextBlock x:Name="JsonText" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}"></TextBlock> <ItemsControl x:Name="TodoList" ItemTemplate="{StaticResource TodoItemTemplate}" Margin="0,12,0,0"></ItemsControl> </StackPanel> </ScrollViewer> </StackPanel>
In der Code Behind Datei fügen wir nun alles zusammen, um die Daten zu schreiben, zu lesen und anzuzeigen.
public async void SaveAndGetTodos() { ToDoService ts = new ToDoService(); string json = await ts.SaveToDos(); List<ToDo> todos = await ts.GetToDos(); JsonText.Text = json; TodoList.ItemsSource = todos; }
Wenn wir unsere Demoanwendung jetzt laufen lassen, sehen wir den JSON String, welcher durch den DataContractJsonSerializer erstellt wurde und außerdem die Liste der Aufgaben im ItemsControl.
Sie können das Beispielprojekt hier herunterladen: http://sdrv.ms/QSJ2yx.
Hoffentlich hat Ihnen das Lesen dieses Artikels Spaß gemacht und Sie haben etwas über async/await und den DataContractJsonSerializer gelernt. Morgen gibt’s mehr über eines der coolsten Features im neuen SDK: die APIs zur Sprachsteuerung.