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.

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

5 Antworten to “WP7 DatePicker Control ohne Eingabefeld verwenden”

  1. Bert Goebel Says:

    Das ‚GetTemplateChild(„DateTimeButton“) as Button‘ liefert mir mit der aktuellen Version (April 2012) der Coding4Fun DLL immer null. In einer früheren Version (ich glaube Juli 2011) hat es funktioniert. Wo könnte der Fehler liegen.

    • René Brunner Says:

      Das DatePicker-Control ist nicht Bestandteil von Coding4Fun, sondern des Silverlight Toolkits, das auch noch mit-installiert wird, weil Coding4Fun teilweise darauf basiert. Wenn ich das jetzt tue, bekomme ich eine Version 4.2011.12.14 des Silverlight Toolkits, mit dem der Button-Klick-Trick bei mir immer noch funktioniert, immer noch mit DateTimeButton als Name. Im Moment habe ich darum keine Idee, was bei Ihnen schieflaufen könnte.

      • Bert Goebel Says:

        Sorry! Ich bin natürlich beim TimeSpan Picker Control aus dem Coding4Fun Toolkit. Mit einer abgeleiteten Klasse von Microsoft.Phone.Controls.TimePicker funktioniert ein ‘GetTemplateChild(“DateTimeButton”) as Button’ – liefert also kein null – Wert zurück. Leite ich allerdings von der Coding4Fun.Phone.Controls.Toolkit.TimeSpanPicker Klasse ab, funktioniert es nicht. Mit einer früheren Version hat dies aber funktioniert. Ehrlich🙂
        Ich denke einfach mal, dass das Template einen anderen Namen hat. Nur welchen?

      • René Brunner Says:

        Ok, ich hab’s, das gute Stück heisst beim TimeSpan-Control neu ValueButton. Solche Dinge findet man wohl am einfachsten heraus, wenn man in Expression Blend eine Kopie des Templates eines Controls erstellt und sich dann anschaut, aus welchen Child Controls sich die Sache zusammensetzt. Im C#-Source-Code würde man es wohl auch irgendwo finden, aber nicht so einfach.

  2. Bert Goebel Says:

    Oh, cool! Vielen Dank!!
    Was habe ich gelernt!? Man sollte sich mal Expression Blend zu Gemüte führen. Auf diese Idee bin wirklich nicht gekommen.
    Ich hoffe, ich kann mich mal revanchieren.


Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: