Share via


Windows Phone 7

Ihre erste Windows Phone-Anwendung

Jesse Liberty

Der Trick beim Schreiben einer allerersten Windows Phone-Anwendung besteht darin, etwas zu erschaffen, das interessant genug ist, um einen Sinn zu haben, und gleichzeitig so einfach ist, dass es auch in die Tat umgesetzt werden kann. Mit diesem Ziel vor Augen möchte ich im Folgenden das Erstellen eines einfachen Dienstprogramms erläutern, das ich jeden Tag verwende: NoteToMe. Die Idee dahinter ist, dass ich in nur einem Schritt eine Nachricht eingeben und an mich selbst senden kann (siehe Abbildung 1).

The NoteToMe Interface
Abbildung 1: Die Benutzeroberfläche von NoteToMe

In diesem Artikel werde ich eine ganze Reihe von Themen kurz ansprechen, die jedoch alle in zukünftigen Artikeln ausführlicher besprochen werden. Zu diesen Themen gehören:

  • Erstellen des Layouts der Anwendung
  • Speichern und Abrufen von Daten aus isoliertem Speicher
  • Ereignisse und Ereignisverarbeitung
  • Erstellen und Ausführen von Aufgaben (Auswahl- und Startprogramme)

Bevor Sie beginnen können, müssen Sie die Tools von http://xbox.create.msdn.com herunterladen. Wenn Sie Ihr Telefon bereits entsperrt, aber noch nicht auf Windows Phone 7.5 („Mango“) aktualisiert haben, ist jetzt der richtige Zeitpunkt dafür. Sie werden von Hunderten neuer Funktionen von Mango profitieren.

Erste Schritte

Wie viele Windows Phone-Entwickler bin ich zu dem Schluss gekommen, dass sich Windows Phone-Anwendungen am besten durch eine Kombination aus Visual Studio (für Code) und Expression Blend (für den Rest) erstellen lassen. Öffnen wir also zuerst Expression Blend, und erstellen wir eine neue Anwendung auf der Grundlage von Windows Phone SDK 7.1. mit dem Namen „NoteToMe“.

Als Erstes ändern wir den Anwendungstitel. Klicken Sie auf den Titel, und suchen Sie im Fenster Eigenschaften die Texteigenschaft für das Steuerelement. Gemäß den Metro-Entwurfsrichtlinien (d. h. den Entwurfsrichtlinien für Windows Phone) muss der Titel in Großbuchstaben geschrieben werden. Ändern Sie den Titel also in NOTE TO ME.

Klicken Sie auf den Seitentitel und dann auf Löschen, um ihn zu entfernen.

Für das Layout benötigen Sie eine kleine Zeile, die sich relativ weit oben auf der Seite befindet. Wenn Sie auf den Rand klicken, erhalten Sie eine Orientierungshilfe, mit dessen Unterstützung Sie visuell die Position der Zeile auswählen können (siehe Abbildung 2).

Placing the Top Row of the Layout
Abbildung 2: Positionieren der obersten Zeile des Layouts

Natürlich können Sie die Zeilengröße auch manuell direkt im XAML festlegen:

<Grid.RowDefinitions>
  <RowDefinition Height="1*"/>
  <RowDefinition Height="9*"/>
</Grid.RowDefinitions>

Das Sternchen nach dem Wert gibt die relative Größe an, in diesem Fall 1:9. Das bedeutet, dass die erste Zeile 1/9 der Größe der zweiten Zeile aufweist. 

Hinzufügen von drei Steuerelementen zum StackPanel

Die oberste Zeile soll drei Steuerelemente enthalten, die nebeneinander liegen:

  • Ein TextBlock-Element für die Beschriftung
  • Ein TextBlock-Element für die E-Mail-Adresse
  • Eine Schaltfläche zum Senden der Nachricht

Dieser Entwurf ist in Abbildung 3 dargestellt.

Three Controls in the Top Row
Abbildung 3: Drei Steuerelemente in der obersten Zeile

Es ist nicht möglich, einer einzigen Zeilenspalte drei Steuerelemente hinzuzufügen, ohne sie in einer Art Container zu organisieren. Ich verwende hierfür einen StackPanel mit horizontaler Ausrichtung: StackPanels können übereinander oder nebeneinander gestapelt werden.

Klicken Sie zum Erstellen eines StackPanels auf der Symbolleiste neben dem Steuerelement Layout auf den kleinen weißen Pfeil (siehe Abbildung 4).

Adding a StackPanel
Abbildung 4: Hinzufügen eines StackPanels

Klicken Sie auf den StackPanel, um das Steuerelement auszuwählen. Ziehen Sie jetzt einen StackPanel in die Zeile, und setzen Sie im Fenster Layout die vertikale und horizontale Ausrichtung auf Strecken und die Ränder auf 0 (siehe Abbildung 5).

Placing the StackPanel
Abbildung 5: Positionieren des StackPanels

Fügen Sie das TextBlock-Element hinzu, und legen Sie für die Schriftgröße 32 und den Text To (Bis) fest. Ziehen Sie jetzt ein TextBox-Element auf den StackPanel. (Beachten Sie den wichtigen, aber subtilen Unterschied zwischen einem TextBlock-Element zum Anzeigen von Text und einem TextBox-Element für die Texteingabe.) Nennen Sie dieses TextBox-Element Address (Adresse). Fügen Sie zum Schluss dem StackPanel eine Schaltfläche hinzu, nennen Sie sie Send (Senden), und legen Sie für Content (Inhalt) Send fest.

Das hierdurch erzeugte XAML wird in Abbildung 6 angezeigt.

Abbildung 6: Entwerfen des StackPanels mit XAML

<StackPanel
  Margin="0"
  Orientation="Horizontal">
  <TextBlock
    Margin="0,8"
    TextWrapping="Wrap"
    Text="To"
    Width="42"
    HorizontalAlignment="Left"
    VerticalAlignment="Center"
    FontSize="32" />
  <TextBox
    x:Name="Address"
    Margin="0,0,0,-7"
    TextWrapping="Wrap"
    Text="foo@bar.com"
    Width="293" />
  <Button
    x:Name="Send"
    Content="Send"
    Margin="0,4,0,0"
    Width="124"
    Click="Send_Click" />
</StackPanel>

Beachten Sie, dass die Schaltfläche Send (Senden) die Eigenschaft Click="Send_Click" aufweist. Dies können Sie erstellen, indem Sie auf die Schaltfläche klicken und anschließend im Fenster Eigenschaften auf die Schaltfläche Ereignisse klicken (siehe Abbildung 7).

The Events Button
Abbildung 7: Die Schaltfläche „Ereignisse“

Hierdurch werden alle Ereignisse für die Schaltfläche geöffnet. Suchen Sie das Klickereignis, und doppelklicken Sie darauf. Die Schaltfläche wird mit dem Ereignis aktualisiert, und Sie werden in den Code-Editor (entweder in Blend oder in Visual Studio, je nach Einrichtung von Blend) für diesen Ereignishandler geleitet. Die Einstellungen für den Ereignishandler müssen Sie zu diesem Zeitpunkt nicht ändern:

private void Send_Click( object sender, RoutedEventArgs e )
{
}

Hinzufügen des Steuerelements für die Nachricht

Klicken Sie auf der Symbolleiste auf das TextBox-Steuerelement, und ziehen Sie ein TextBox-Element so, dass es die Hälfte der restlichen Seite ausfüllt (die andere Hälfte ist für die Tastatur vorgesehen, die angezeigt wird, wenn Eingaben für das TextBox-Steuerelement vorgenommen werden müssen). Setzen Sie HorizontalAlignment (Horizontale Ausrichtung) auf Strecken, VerticalAlignment (Vertikale Ausrichtung) auf Oben und die Ränder auf 0. Setzen Sie die Breite auf Auto und die Höhe auf 244. Sie können dies nach Augenmaß ausführen, während Sie die Größe für das TextBox-Element festlegen, oder Sie können das TextBox-Element grob positionieren und die Eigenschaften im Fenster Eigenschaften festlegen (siehe Abbildung 8).

Adding the TextBox
Abbildung 8: Hinzufügen des TextBox-Elements

Schreiben des Codes

Jetzt haben Sie die Steuerelemente eingerichtet und können an der Logik des Programms arbeiten. Links oben wird eine Registerkarte namens Projekte angezeigt. Klicken Sie nach dem Speichern der Änderungen auf die Registerkarte Projekte, klicken Sie dann mit der rechten Maustaste auf MainPage.xaml.cs, und wählen Sie In Visual Studio bearbeiten aus (siehe Abbildung 9).

Getting Ready to Write the Code
Abbildung 9: Vorbereitung auf das Schreiben des Codes

Vorgaben

Nach meiner mir selbst auferlegten Vorgabe sollten Benutzer nicht jedes Mal, wenn sie das Programm verwenden, die Einträge im Feld To (An) erneut vornehmen müssen, sondern es sollte ihnen möglich sein, die Einträge vom letzten Mal zu verwenden.

Darüber hinaus sollte beim Klicken auf Send(Senden) für das E-Mail-Programm bereits eine neue E-Mail-Nachricht mit allen aufgefüllten Feldern vorbereitet sein, sodass der Benutzer nur Send drücken muss oder bei Bedarf zuvor die Nachricht bearbeiten kann und dann Send drückt.

Isolierter Speicher

Um den Inhalt des Felds To (An) für verschiedene Verwendungen der Anwendung zu sichern, müssen Sie ihn auf dem Telefon speichern. An dieser Stelle kommt der isolierte Speicher ins Spiel: Er ermöglicht die Speicherung der Daten nach dem Schließen der Anwendung. Wie der Name nahelegt, können mithilfe von isoliertem Speicher Daten Ihrer Anwendung isoliert und geschützt von den Daten anderer Anwendungen gespeichert werden. Die Verwendung von isoliertem Speicher ist ziemlich einfach.

Fügen Sie zuerst die folgende using-Anweisung hinzu:

using System.IO.IsolatedStorage;

Deklarieren Sie eine Membervariable vom Typ IsolatedStorageSettings und eine const-Zeichenfolge, die als Schlüssel zum Wörterbuch für isolierten Speicher dient, sodass Sie die E-Mail-Adresse speichern und abrufen können:

private IsolatedStorageSettings _isoSettings;
const string IsoKey = "EmailAddress";
Initialize the _isoSettings member in the constructor:
 _isoSettings = IsolatedStorageSettings.ApplicationSettings;

Speichern und Abrufen der E-Mail-Adresse

Die zwei Aufgaben für den isolierten Speicher sind das Speichern und das Abrufen der Zeichenfolge. Das Speichern wird am besten beim Verlassen der Seite durchgeführt. Wenn Sie die Windows Phone-Seite verlassen, wird die OnNavigatedFrom-Methode aufgerufen. Sie können sie überschreiben. Ein guter Grund hierfür ist das Speichern von Daten in isoliertem Speicher:

protected override void OnNavigatedFrom(
  System.Windows.Navigation.NavigationEventArgs e )
{
  _isoSettings[IsoKey] = Address.Text;
  base.OnNavigatedFrom( e );
}

Jetzt haben Sie die E-Mail-Adresse im _isoSettings-Wörterbuch unter dem IsoKey-Schlüssel gespeichert. Wenn Sie zu dieser Seite zurückkehren, können Sie diese Einstellung wiederherstellen. Ich rufe hierfür die RestoreEmailAddress-Hilfsmethode vom Typ „private“ vom Konstruktor auf:

private void RestoreEmailAddress()
  {
    if (_isoSettings.Contains( IsoKey ))
      Address.Text = _isoSettings[IsoKey].ToString();
  }

Beachten Sie, dass ich das Vorhandensein des Schlüssels im isolierten Speicher vor der Wiederherstellung überprüfe. Dadurch wird das Auslösen einer KeyNotFound-Ausnahme beim ersten Ausführen des Programms verhindert. Denken Sie daran: Bei der ersten Ausführung des Programms haben Sie noch nichts im isolierten Speicher gespeichert.

Ebenso wenig ist das Adressfeld beim ersten Start des Programms ausgefüllt. Sobald der Benutzer eine E-Mail-Adresse in das Adressfeld eingibt, wird die Adresse im isolierten Speicher gespeichert und bei der nächsten Ausführung des Programms wiederhergestellt. Falls der Benutzer die Adresse ändert, wird die neue Adresse gespeichert.

Aufgaben

Windows Phone 7.5 unterstützt eine Anzahl von Aufgaben zur Interaktion mit integrierten Telefonanwendungen (E-Mail, Kontaktliste, Kamera usw.). Es gibt zwei Arten von Aufgaben: Auswahl- und Startprogramme. Mit Auswahlprogrammen werden Informationen ausgewählt und an das Programm zurückgegeben (zum Beispiel, um eine E-Mail-Adresse von der Kontaktliste abzurufen). Startprogramme werden zum Starten eines Programms verwendet, das keine Daten zurückgibt.

In diesem Fall haben Sie alles, was Sie zum Senden der Nachricht benötigen. Also können Sie das E-Mail-Startprogramm aufrufen und die erforderlichen Felder ausfüllen. Beim Aufrufen von Show im E-Mail-Startprogramm wird die E-Mail-Anwendung mit Ihren Daten gestartet. Sie erhalten jedoch keine Daten zurück (was in Ordnung ist, denn Sie benötigen sowieso keine).

Nach dem Senden der E-Mail wird das Programm erneut angezeigt, falls Sie eine weitere Nachricht senden möchten.

Alle Daten der Erstellung des Startprogramms sind im Click-Ereignishandler für die Schaltfläche Send (Senden) gekapselt. Starten wir mit dem Erstellen einer Instanz von EmailComposeTask (dem Startprogramm). Füllen Sie die Felder aus, und rufen Sie Show auf. Das ist auch schon alles:

private void Send_Click( object sender, RoutedEventArgs e )
{
  EmailComposeTask emailComposeTask = new EmailComposeTask();
  emailComposeTask.Subject = "Send To Me";
  emailComposeTask.To = Address.Text;
  emailComposeTask.Body = Message.Text;
  Message.Text = String.Empty;
  emailComposeTask.Show();
}

Beim Aufrufen von Show werden der Betreff, die Adresse und der Nachrichtentext an Ihre E-Mail-Anwendung weitergeleitet. Wenn Sie über mehrere E-Mail-Anwendungen verfügen, können Sie wählen, welche Sie verwenden möchten. Es wird eine ordnungsgemäß adressierte und formatierte E-Mail-Adresse erstellt, die Sie sofort verwenden können.

Anwendungslebenszyklus

Wenn Benutzer niemals die Verwendung Ihrer Anwendung vor dem Versenden ihrer Nachricht unterbrechen würden, wären Sie jetzt fertig. Tatsächlich unterbrechen Benutzer das Schreiben einer Nachricht häufig und starten plötzlich eine andere Anwendung. Wenn sie anschließend ihre Nachricht weiterschreiben möchten, wären sie nicht sonderlich erfreut, wenn diese verschwunden wäre.

Um dies zu verhindern, sollten Sie den Lebenszyklus einer Anwendung ein wenig verstehen und wissen, wie ein Zustand gesichert und gleichzeitig eine der leistungsstärksten Funktionen von Mango unterstützt werden kann: Schnelle Anwendungsumschaltung.

Wenn Ihre Anwendung gestartet wird (zum Beispiel über das Startmenü), wird das Application_Launching-Ereignis ausgelöst. Sobald die Anwendung startet und jedes Mal, wenn der Benutzer zu Ihrer Seite navigiert, wird die OnNavigatedTo-Methode aufgerufen. Hierdurch wird Ihre Seite in den Ausführungsstatus versetzt. Wenn der Benutzer eine neue Anwendung startet, empfängt Ihre Anwendung das Application.Deactivated-Ereignis und wird in einen inaktiven Zustand versetzt. Wenn das Telefon nicht über genügend Arbeitsspeicher verfügt, erfolgt ein Tombstoning der Anwendung.

In diesem oder im inaktiven Zustand kann die Anwendung beendet oder wiederhergestellt werden. Wichtiger ist jetzt jedoch, was geschieht, wenn die Anwendung wiederhergestellt wird.

Wenn die Anwendung inaktiv ist, müssen Sie nicht nur bei der Wiederherstellung keine Aktion ergreifen, sondern Sie möchten auch gar nichts unternehmen: Der Zustand wurde gespeichert, als die Anwendung inaktiv war, und sie ist jetzt aktionsbereit.

Wenn jedoch ein Tombstoning der Anwendung erfolgte, möchten Sie den Zustand der Seite beim erneuten Aufrufen der Anwendung wiederherstellen. Der Benutzer erhält somit den Eindruck, dass die Anwendung ausgeführt wurde (oder zumindest inaktiv war), während er mit der anderen Anwendung gearbeitet hat.

Sie stehen somit vor zwei Aufgaben:

  1. Speichern des Zustands, wenn die OnNavigatedFrom-Methode der Seite aufgerufen wird
  2. Möglicherweise Wiederherstellen des Zustands, wenn die OnNavigatedTo-Methode der Seite aufgerufen wird; Wiederherstellen des Zustands, wenn ein Tombstoning der Anwendung erfolgte, jedoch nicht, wenn sie inaktiv war

Speichern des Zustands, wenn die Seite verschwindet

Da Sie nicht wissen, wann die Seite die OnNavigatedFrom-Methode empfängt und in welchem Zustand sie sich bei der Wiederherstellung befindet, muss der Zustand für alle Fälle gespeichert werden. Dies ist ganz einfach: Sie verwenden ein State-Wörterbuch, dessen Syntax dem Wörterbuch des isolierten Speichers sehr ähnelt. Denken Sie aber daran, dass das State-Wörterbuch nicht in den dauerhaften Speicher geschrieben wird und beim Beenden des Programms oder Ausschalten des Telefons gelöscht wird.

Erstellen wir zunächst eine const-Zeichenfolge StateKey, die Sie als Offset des State-Wörterbuchs verwenden:

const string StateKey = "MessageState";

Speichern Sie in der OnNavigatedFrom-Methode den Zustand (in diesem Fall den Inhalt von MessageBox) im State-Wörterbuch:

protected override void OnNavigatedFrom(
  System.Windows.Navigation.NavigationEventArgs e )
{
  _isoSettings[IsoKey] = Address.Text;
  State[StateKey] = Message.Text;
  base.OnNavigatedFrom( e );
}

Wiederherstellen von State, wenn die Seite erstellt wird

Beim Aufrufen der OnNavigatedTo-Methode möchten Sie keine Aktion zum Wiederherstellen von State ergreifen, wenn die Anwendung inaktiv war. Falls jedoch ein Tombstoning der Anwendung erfolgte, möchten Sie etwas tun.

Sie können zwischen dem inaktiven und Tombstone-Zustand unterscheiden, indem Sie ein Flag auf FALSE und anschließend im Konstruktor auf TRUE setzen. Wenn die Anwendung inaktiv ist, wird der Konstruktor nicht aufgerufen. Falls ein Tombstoning erfolgte, wird der Konstruktor aufgerufen (weil die Erstellung zum ersten Mal erfolgt), wie im Folgenden dargestellt:

bool isNew = false;
  public MainPage()
  {
    InitializeComponent();
    isNew = true;

Sie können das Flag in OnNavigatedTo überprüfen:

protected override void OnNavigatedTo(
  System.Windows.Navigation.NavigationEventArgs e )
{
  if (isNew)
  {
    if (State.ContainsKey( StateKey ))
    {
      Message.Text = State[StateKey].ToString();
    }
  }
  isNew = false;
  base.OnNavigatedTo( e );
}

Mit dem Test sparen Sie Zeit, die Sie andernfalls für das Wiederherstellen des Werts aus dem State-Wörterbuch aufwenden müssten. Führen Sie den Test durch, indem Sie zuerst das Programm normal ausführen (in diesem Fall wird das Programm beim Wechseln zu einem anderen Programm inaktiv) und dann ein Tombstoning des Programms erzwingen. Sie können ein Tombstoning Ihres Programms erzwingen, indem Sie mit der rechten Maustaste auf das Projekt klicken, Eigenschaften auswählen, die Registerkarte Debug (Debuggen) wählen und das Kontrollkästchen Tombstone upon deactivation while debugging (Bei Deaktivierung Tombstoning beim Debuggen) aktivieren.

Bei einer Ausführung mit aktiviertem Kontrollkästchen stellen Sie eine deutliche Pause beim Zurückkehren zur Seite fest, weil der Zustand wiederhergestellt werden muss.

Zusammenfassung

In diesem kurzen Artikel habe ich Ihnen gezeigt, wie Sie Ihre erste anspruchsvolle Windows Phone-Anwendung schreiben. Zuerst habe ich die Anwendung in Expression Blend erstellt, indem ich eine Zeile erstellt und einen StackPanel zum Erzeugen der Steuerelemente verwendet habe.

Dann bin ich zu Visual Studio gewechselt, um die Logik für den Ereignishandler der Schaltfläche zu schreiben. Außerdem habe ich mithilfe von isoliertem Speicher die E-Mail-Adresse gespeichert. Ich habe State-Arbeitsspeicher verwendet, um sicherzustellen, dass die Anwendung nach dem Tombstoning ordnungsgemäß erneut startet.

Wie bereits erwähnt, kann jedes dieser Themen noch eingehender behandelt werden, was in zukünftigen Artikeln erfolgen soll.

Jesse Liberty ist ein leitender Experte der Entwicklercommunity im Windows Phone-Team. Er hostet den beliebten „Yet Another Podcast“ (jesseliberty.com/podcast), und sein Blog (jesseliberty.com/) ist sehr lesenswert. Jesse Liberty ist Autor vieler Bestseller, einschließlich „Programming Reactive Extensions and LINQ“ (Apress, 2011) und „Migrating to Windows Phone“ (Apress, 2011). Sie können ihn auf Twitter unter twitter.com/JesseLiberty erreichen.

Unser Dank gilt den folgenden technischen Experten für die Durchsicht dieses Artikels: Drew Batchelor und Cheryl Simmons.