WP7 DatePicker Control ohne Eingabefeld verwenden

Im Silverlight Toolkit für Windows Phone 7 gibt es ein recht hübsches Control für die Eingabe eines Datums, das DatePicker Control. Es besteht aus der Kombination einer Textbox, welche das aktuell gültige bzw. gewählte Datum anzeigt, und einer eigenen vollen Seite, auf der man das Datum „touch-gerecht“ eingeben kann; man errreicht diese Eingabeseite, in dem man die Textbox antippt. Einen Überblick über die Verwendung des Controls in einem Programm gibt es z.B. hier.

Ich wollte das Control etwas anders verwenden, ohne Textbox als Eingabefeld: Die Eingabeseite sollte auf ein Menukommando hin erscheinen, und das gewählte Datum zum Text in einer Textbox hinzugefügt werden.

Ein solches Anwendungsszenario ist von den Machern des Controls nicht vorgesehen, aber mit ein bisschen Tricksen geht es doch:

Um das Control programmatisch auszulösen und auf die Eingabeseite zu gelangen, muss man das Antippen der Textbox simulieren. Das geht, indem man eine eigene Klasse von DatePicker ableitet, damit man an einen Button herankommt, der ein Kind der Textbox ist, und diesen Button per Code „drückt“:

  public class CustomDatePicker : DatePicker {
    public void ClickTemplateButton() {
      Button button = (GetTemplateChild("DateTimeButton") as Button);
      ButtonAutomationPeer peer = new ButtonAutomationPeer(button);
      IInvokeProvider provider = (peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider);
      provider.Invoke();
    }
  } 

Gefunden hatte ich diesen Trick auf einer Website namens wp7-developer.com, aber diese ist offenbar einem Besitzerwechsel zum Opfer gefallen. Interessanterweise behaupten die Antworten zu dieser Frage auf Stack Overflow, es gäbe keine solche Möglichkeit.

Beim API-Minimalismus, der allgemein bei WP7 herrscht, habe ich mich übrigens gewundert, dass es eine Klasse wie ButtonAutomationPeer überhaupt gibt. Vielleicht hat ja bei der Implementation von Silverlight für WP7 nur jemand vergessen, diese Klasse zu löschen…

Auf der Eingabeseite gibt es 2 Buttons, einen, um das Datum zu akzeptieren, und einen, um die Wahl zu verwerfen. Normalerweise führt das Control selbständig seine Value-Property nach oder eben nicht, je nach dem, wie der Benutzer die Eingabeseite verlässt, und man muss im Programm nichts davon wissen.

In meinem Nicht-Standard-Anwendungsfall sieht das allerdings etwas anders aus: Bei Eingabe akzeptiert soll der Datumstext eingefügt werden, bei Eingabe verworfen nicht. Wie kriegt man das hin? Eine erste Suche nach einer Property, welche direkt aussagt, wie die Eingabe endete, war erfolglos.

Das DatePicker-Control bietet den üblichen ValueChanged-Event an, an den man sich hängen kann, um mitzubekommen, wenn der Wert ändert. Das Problem: Wenn der Wert nicht ändert, dann auch kein ValueChanged, selbst wenn der Benutzer die Eingabe bestätigt. Der Effekt bei Verwendung dieses Events ist darum, dass eine Eingabe des voreingestellten Datums nicht möglich ist.

Es gibt allerdings eine ganz einfache Lösung: DatePicker.Value ist nullable. Setzt man die Property auf null vor Aufruf des Controls, ist hinterher die Property gesetzt, wenn der Anwender bestätigte, und immer noch null, wenn er die Eingabe abbrach.

Die Implementation des Controls als eigene Seite mit einem Verhalten, das einem Popup entspricht, hat übrigens einige ganz interessante Aspekte, welche hier näher erläutert werden.

Advertisements
Veröffentlicht in Allgemein. Schlagwörter: , . 5 Comments »

Das Monster im WP7-Clipboard

Es ist keine besonders wichtige Geschichte, die ich heute erzähle, aber loswerden will ich sie trotzdem, denn ich finde sie einigermassen süss:

Ich wollte für meine im Bau begriffene WP7 App eine Funktion programmieren, die einen im Clipboard vorhandenen Text nimmt, ihn analysiert und dann dem Benutzer auf eine intelligente Weise zur Verfügung stellt: Die App würde eine Liste erstellen aller spezieller „Dinge“ im Text wie URLs, Mail-Adressen und Telefonnummern, und der Benutzer könnte anschliessend diese Dinge durch einfaches Antippen verwenden. Eben eine verallgemeinerte Variante der WP7-Standard-Funktionalität, die in SMS-Texten (aber nur solchen) aus Dingen antippbare Links macht.

Dabei musste ich feststellen, dass es einer WP7-Applikation nicht erlaubt ist, den Clipboard-Inhalt auszulesen. Das ist nur interaktiv durch den Benutzer ausgelöst möglich. Siehe entsprechende Info im MSDN. Es nützt überhaupt nichts, dass die entsprechende Methode Clipboard.GetText da ist und man sie ohne Probleme in seinen Code aufnehmen kann – der Versuch, sie auszuführen, ergibt knallhart stets eine SecurityException.

Gegenüber anderen Einschränkungen des WP7-API ist das ein kleiner Fisch, aber trotzdem: Was soll das mit Sicherheit zu tun haben? Was haben sich die Microsoft-Programmierer dabei gedacht, als sie diese Einschränkung einführten, gegen welches Bedrohungs-Szenario richtet sie sich?

Es kann eigentlich kaum daran liegen, dass im WP7-Clipboard irgendein Monster sitzen könnte, gegen das man Programme schützen müsste, welche den Clipboard-Inhalt auslesen. Das Clipboard kann sowieso nur Text enthalten (eine weitere Einschränkung, bei der man nicht so recht weiss, was man davon halten soll), und auch wenn man mit Hilfe von Unicode einigen Blödsinn anstellen kann, eine Bedrohung kriegt man so wohl kaum zustande.

Soll die Limitation ein Schutz sein gegen bösartige Programme, welche den Benutzer über den Inhalt des Clipboards ausspionieren? Programm wartet im Hintergrund, bis der Anwender das hochgeheime Passwort per Copy&Paste von einer App in die nächste transportiert, schnappt sich dieses, während es im Clipboard sitzt, sendet es zum Server der Verbrecher, und das Unheil nimmt seinen Lauf?

Aber sicher doch.

Vor allem, da ja in WP7 das Multitasking von Apps so toll ausgebaut ist, dass man überhaupt im Hintergrund warten könnte, bis etwas Interessantes im Clipboard auftaucht.

Meine Vermutung ist, dass die Jungs und Mädels bei Microsoft schlicht über’s Ziel hinausgeschossen sind. Gebrannt durch die lange Leidensgeschichte von Windows auf dem PC, was Sicherheit bzw. die ziemliche Abwesenheit derselben betrifft, will man wohl jetzt unter allen Umständen vermeiden, dass WP7 mit irgendeiner Sicherheitslücke Negativ-Schlagzeilen macht.

Wenn man also nicht zu 100% sicher sein kann, dass nichts aus dem Ruder läuft, wenn man den Apps Clipboard-Lese-Zugriff einräumt, lässt man lieber die Finger davon: Better safe than sorry.

Veröffentlicht in Allgemein. Schlagwörter: . 1 Comment »