Surface: Scatterview und auftauchende Elemente

Wenn man mit Microsoft Surface ein Element auftauchen lassen will, so soll dies danach auch sich bewegen, ziehen und auch drehen lassen. Dazu bietet sich der Scatterview an. Das Auftauchen von Elementen lässt sich leicht lösen, wenn diese frei und unabhängig vom Rest sind, also ein eigenständiges ScatterviewItem

 <s:ScatterViewItem x:Name="MobileContainer" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="110" Height="240" 
                               Background="{x:Null}" BorderBrush="{x:Null}" Center="400,400" CanScale="False" Visibility="Collapsed">
                <controls:Handy x:Name="Mobile"></controls:Handy>
            </s:ScatterViewItem>
Das vorher versteckte Item wird einfach von "Collapsed" oder "Hidden" in der Visibility auf Visible gesetzt. Das kann ich also tun, wenn wie in dem Fall oben, gewünscht wird, dass ein optischer Kontakt mit einer Benutzeroberfläche dann auf dem Surface erscheint, wenn das Handy auf die Oberfläche gelegt wird (mit Hilfe von TagVisualization). Doch damit nicht genug. Auf Knopfdruck soll um das Handy herum eine Anzahl von Fotos erscheinen, die aus dem Handy stammen. Das kann man auch mit ScatterViewItems lösen und es scheint dies der einfache Weg.
            <s:ScatterViewItem Background="Red" x:Name="HandyPic" Center="0,146" Width="120" Height="80" Orientation="-18" Visibility="Collapsed">
                <Image Source="/CameraVisualizations;Component/Media/handypic1.jpg" Stretch="UniformToFill"/>
            </s:ScatterViewItem>

Die ScatterViewItems lassen sich auch per Code erzeugen, doch der Einfachheit halber, habe ich sie oben als XAML dargestellt. Der ScatterView hat allerdings eine nervige Eigenschaft: neue Items erscheinen nicht einfach unter den alten, sondern auf einer festgeleten Position oder einfach irgendwo auf der Oberfläche. Daher müssen wir das Item zu dem anderen legen. Dies geschieht, in dem ich im Code mir die Properties des "MobileContainer" betreffend Center und Orientation hole und sie etwas modifiziert dem "HandyPic" zuweise. Eine ganz einfache Sache.

Doch wie steht es mit der Anforderung, dass die Bilder zuerst klein sind und in einem Haufen unter dem Handy liegen, und dann "herausgezogen" werden können? Dann müssten sich alle ScatterViewItems der Bilder zusammen mit dem ScatterviewItem des Handys bewegen, sobald dieses bewegt wird. Das endet schnell in Ruckelei und sieht gar nicht gut aus. Abhilfe schafft nur, die Integration der Handybilder in das ScatterViewItem des Handys. Das bedeutet, dass alle Bilder zuerst Teil des controls "Handy" werden und in diesem erzeugt werden und somit flüssig damit bewegt werden können. Erst wenn eine Geste oder ein Kontakt dafür sorgen soll, dass die Handybilder aus dem Handy herausflutschen oder gezogen werden, wird ein entsprechendes ScatterViewItem erzeugt und an die Stelle des Items gesetzt, dass zuvor Teil des HandyControls war. Leider stoßen wir dabei an ein ziemliches Problem: wir müssen die Koordinaten, die zuvor intern und relativ zum Control Handy gehörten, nun umrechnen auf den umfassenden ScatterView. Ein scheinbar nerviges Rechnen steht uns bevor. Gar nicht schön.

Doch zum Glück gibt es die Klasse "GeneralTransform" die ist leidlich unbekannt, erledigt aber in einem Zweizeiler das ganze für uns.

GeneralTransform gt = internesHandyPic.TransformToVisual(bigScatterView);
thePoint = gt.Transform(thePoint);

Damit können wir also recht genau den Punkt berechnen, wo sich unser internes Handy Bild befindet und es auf den großen ScatterView erscheinen soll und damit können wir es austauschen. Das externe ScatterViewItem entsteht und wird über dem internen paßgenau gezeigt, das interne Bild des Control Handy wird versteckt. Durch eine kleine Animation wird der Wechsel für den Anwender unsichtbar.

 

Filed under:

Comments

No Comments

Leave a Comment

(required) 
(required) 
(optional)
(required)