Neue Benutzeroberflächentechnologien

Ereignisse für Mehrfingereingaben in WPF

Charles Petzold

Beispielcode herunterladen.

Charles PetzoldInnerhalb von nur wenigen Jahren haben sich Mehrfingereingaben von einer futuristischen Vorstellung in Science-Fiction-Filmen zu einer üblichen Benutzereingabetechnik entwickelt. Multitouch-Bildschirme gehören bei neuen Smartphone-Modellen und Tablet PCs nun zur Standardausrüstung. Multitouch-Bildschirme werden sicherlich auch auf Computern an öffentlichen Standorten universell eingesetzt werden, wie zum Beispiel bei Kiosksystemen oder Table-Computern, bei denen Microsoft Surface eine Vorreiterrolle einnimmt.

Bei herkömmlichen Desktopcomputern erfreuen sich Mehrfingereingaben großer Beliebtheit – dies könnte jedoch einen Unsicherheitsfaktor darstellen. Das womöglich größte Hindernis besteht in den Ermüdungserscheinungen, dem so genannten „Gorilla-Arm“, da die Finger über einen langen Zeitraum auf vertikalen Bildschirmen bewegt werden. Ich persönlich hoffe, dass die Leistungsstärke der Multitouch-Bildschirme tatsächlich zu einer Neugestaltung von Desktopanzeigen führt. Ich kann mir sehr gut einen Desktopcomputer mit einer Anzeige vorstellen, die der Konfiguration eines Zeichenbretts ähnelt – und womöglich nahezu die gleiche Größe aufweist.

Dies ist jedoch (vielleicht) noch Zukunftsmusik. Derzeit müssen sich Entwickler erstmal mit neuen APIs vertraut machen. Die Unterstützung von Mehrfingereingaben in Windows 7 wurde auf verschiedene Bereiche in .NET Framework mit High- und Low-Schnittstellen konzentriert.

Regeln einer Multitouch-Unterstützung

Wenn Sie die Komplexität von Ausdrücken bedenken, die durch Mehrfingereingaben auf einer Anzeige möglich sind, verstehen Sie vielleicht, warum anscheinend niemand die „korrekte“ Programmierschnittstelle für Multitouch-Bildschirme kennt. Dies wird eine gewisse Zeit dauern. In der Zwischenzeit stehen Ihnen verschiedene Optionen zur Verfügung.

Windows Presentation Foundation (WPF) 4.0 verfügt über zwei Multitouch-Benutzeroberflächen für Programme unter Windows 7. Für spezielle Verwendungen der Mehrfingereingaben müssen Programmierer die Low-Level-Schnittstelle untersuchen, die aus mehreren Routingereignissen besteht. Diese Ereignisse werden durch das UIElement mit der Bezeichnung TouchDown, TouchMove, TouchUp, TouchEnter und TouchLeave definiert und bieten Vorschauversionen der down-, move- und up-Ereignisse. Diese wurden offensichtlich nach Mausereignissen modelliert, mit der Ausnahme, dass eine Ganzzahl-ID-Eigenschaft zum Verfolgen der Mehrfingereingaben auf der Anzeige erforderlich ist. Microsoft Surface basiert auf WPF 3.5, unterstützt jedoch eine umfassendere Low-Level-Kontaktschnittstelle, die zwischen Arten und Formen der Fingereingaben unterscheidet.

Dieser Artikel beschäftigt sich mit der Multitouch-Unterstützung für High-Level-Schnittstellen in WPF 4.0, die aus einer Sammlung von Ereignissen besteht, deren Namen mit dem Wort „Manipulation“ beginnen. Diese Manipulationsereignisse führen mehrere wichtige Multitouch-Aufgaben aus:

  • Konsolidieren der Interaktion von zwei Fingern in eine einzelne Aktion
  • Auflösen der Bewegung eines Fingers oder zweier Finger in Transformationen
  • Implementieren einer Trägheit, wenn die Finger vom Bildschirm genommen werden

Eine Teilmenge von Manipulationsereignissen wird in der Silverlight 4-Dokumentation angegeben, dies ist jedoch ein wenig irreführend. Die Ereignisse werden noch nicht von Silverlight unterstützt, sondern nur von den für Windows Phone 7 geschriebenen Silverlight-Anwendungen. Die Manipulationsereignisse werden in Abbildung 1 aufgeführt.

Abbildung 1 Manipulationsereignisse in Windows Presentation Foundation 4.0

Ereignis Von Windows Phone 7 unterstützt?
ManipulationStarting Nein
ManipulationStarted Ja
ManipulationDelta Ja
ManipulationInertiaStarted Nein
ManipulationBoundaryFeedback Nein
ManipulationCompleted Ja

 

Webbasierte Silverlight 4-Anwendungen verwenden weiterhin das Ereignis „Touch.FrameReported“, das im Artikel „Finger Style: Einführung in die Multitouch-Unterstützung in Silverlight“ in der MSDN Magazin-Ausgabe von März 2010 erörtert wurde.

Zusammen mit den Manipulationsereignissen selbst unterstützt die UIElement-Klasse in WPF auch überschreibbare Methoden wie „OnManipulationStarting“, die den Manipulationsereignissen entsprechen. In Silverlight für Windows Phone 7 werden diese überschreibbaren Methoden durch die Control-Klasse definiert.

Ein Beispiel für Mehrfingereingaben

Die typische Multitouch-Anwendung ist möglicherweise eine Fotoanzeige, auf der Sie Fotos auf einer Oberfläche verschieben und mit zwei Fingern vergrößern, verkleinern und drehen können. Diese Vorgänge werden häufig als Schwenken, Zoomen und Drehen bezeichnet und entsprechen den Standard-Grafiktransformationen der Übersetzung, Skalierung und Rotation.

Natürlich muss ein Programm zum Betrachten von Fotos die Fotosammlungen beibehalten, das Hinzufügen neuer Fotos bzw. das Entfernen von Fotos ermöglichen und eventuell die Fotos in einem kleinen Grafikrahmen anzeigen. Diese Aspekte werde ich nicht erörtern, sondern mich einfach auf die Multitouch-Interaktionen beschränken. Ich war äußerst überrascht – genauso wie Sie vielleicht – wie leicht dies alles mit den Manipulationsereignissen zu erreichen ist.

Alle Quellcodes für diesen Artikel liegen in einer herunterladbaren Lösung mit dem Namen „WpfManipulationSamples“ vor. Das erste Projekt lautet „SimpleManipulationDemo“, und die Datei „MainWindow.xaml“ ist in Abbildung 2 dargestellt.

Abbildung 2 Die XAML-Datei für das SimpleManipulationDemo-Projekt

<Window x:Class="SimpleManipulationDemo.MainWindow"
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  Title="Simple Manipulation Demo">

  <Window.Resources>
    <Style TargetType="Image">
      <Setter Property="Stretch" Value="None" />
      <Setter Property="HorizontalAlignment" Value="Left" />
      <Setter Property="VerticalAlignment" Value="Top" />
    </Style>
  </Window.Resources>

  <Grid>
    <Image Source="Images/112-1283_IMG.JPG"  
      IsManipulationEnabled="True"
      RenderTransform="0.5 0 0 0.5 100 100" />

    <Image Source="Images/139-3926_IMG.JPG"
      IsManipulationEnabled="True"
      RenderTransform="0.5 0 0 0.5 200 200" />
        
    <Image Source="Images/IMG_0972.JPG"
      IsManipulationEnabled="True"
      RenderTransform="0.5 0 0 0.5 300 300" />
        
    <Image Source="Images/IMG_4675.JPG"
      IsManipulationEnabled="True"
      RenderTransform="0.5 0 0 0.5 400 400" />
  </Grid>
  </Window>

Achten Sie zuerst auf die Einstellung aller drei Bildelemente:

IsManipulationEnabled="True"

Diese Eigenschaft ist standardmäßig auf „False“ eingestellt. Sie müssen sie für jedes Element, für das Mehrfingereingaben erreicht und Manipulationsereignisse erzeugt werden sollen, auf „True“ setzen.

Bei den Manipulationsereignissen handelt es sich um WPF-Routingereignisse. Dies bedeutet, dass die Ereignisse in einer visuellen Struktur eingeblendet werden. In diesem Programm ist weder für das Grid- noch für das MainWindow-Element die Eigenschaft „IsManipulationEnabled“ auf „True“ eingestellt. Sie können jedoch weiterhin Handler für die Manipulationsereignisse an die Grid- und MainWindow-Elemente anfügen oder die OnManipulation-Methoden in der MainWindow-Klasse überschreiben.

Für jedes der Bildelemente ist die Eigenschaft „RenderTransform“ auf eine sechsstellige Zeichenfolge festgelegt:

RenderTransform="0.5 0 0 0.5 100 100"

Dies ist eine Verknüpfung, mit der die Eigenschaft „RenderTransform“auf ein initialisiertes MatrixTransform-Objekt eingestellt wird. In diesem bestimmten Fall wird das auf die Eigenschaft „MatrixTransform“ eingestellte Matrix-Objekt initialisiert, um eine Skalierung von 0,5 (Verkleinern der Fotos auf ihre halbe Größe) und eine Übersetzung von 100 Einheiten nach rechts und unten vorzunehmen. Die Code-Behind-Datei für das Fenster ruft diese MatrixTransform-Eigenschaft auf und ändert sie.

Die vollständige Datei „MainWindow.xaml.cs“, mit der nur die zwei Methoden „OnManipulationStarting“ und „OnManipulationDelta“ überschrieben werden, ist in Abbildung 3 dargestellt. Mit diesen Methoden werden die von den Bildelementen generierten Manipulationen verarbeitet.

Abbildung 3 Die Code-Behind-Datei für das SimpleManipulationDemo-Projekt

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace SimpleManipulationDemo {
  public partial class MainWindow : Window {
    public MainWindow() {
      InitializeComponent();
    }

    protected override void OnManipulationStarting(
      ManipulationStartingEventArgs args) {

      args.ManipulationContainer = this;

      // Adjust Z-order
      FrameworkElement element = 
        args.Source as FrameworkElement;
      Panel pnl = element.Parent as Panel;

      for (int i = 0; i < pnl.Children.Count; i++)
        Panel.SetZIndex(pnl.Children[i],
          pnl.Children[i] == 
          element ? pnl.Children.Count : i);

      args.Handled = true;
      base.OnManipulationStarting(args);
    }

    protected override void OnManipulationDelta(
      ManipulationDeltaEventArgs args) {

      UIElement element = args.Source as UIElement;
      MatrixTransform xform = 
        element.RenderTransform as MatrixTransform;
      Matrix matrix = xform.Matrix;
      ManipulationDelta delta = args.DeltaManipulation;
      Point center = args.ManipulationOrigin;

      matrix.ScaleAt(
        delta.Scale.X, delta.Scale.Y, center.X, center.Y);
      matrix.RotateAt(
        delta.Rotation, center.X, center.Y);
      matrix.Translate(
        delta.Translation.X, delta.Translation.Y);
      xform.Matrix = matrix;

      args.Handled = true;
      base.OnManipulationDelta(args);
    }
  }
  }

Manipulation – Grundlagen

Eine Manipulation ist als eine Berührung eines bestimmten Elements durch einen oder zwei Finger definiert. Eine vollständige Manipulation beginnt mit dem Ereignis „ManipulationStarting“ (kurz darauf gefolgt vom Ereignis „ManipulationStarted“) und endet mit dem Ereignis „ManipulationCompleted“. Dazwischen können sich viele ManipulationDelta-Ereignisse befinden.

Jedes der Manipulationsereignisse wird von einem eigenen Satz Ereignisargumente begleitet, die in einer Klasse eingeschlossen sind. Diese Klasse wird nach dem Ereignis mit dem angefügten Ereignisargument „EventArgs“ benannt, zum Beispiel „ManipulationStartingEventArgs“ und „ManipulationDeltaEventArgs“. Diese Klassen sind vom bekannten Ereignisargument „InputEventArgs“ abgeleitet, das wiederum vom Ereignisargument „RoutedEventArgs“ stammt. Die Klassen enthalten die Eigenschaften „Source“ und „OriginalSource“ und weisen darauf hin, woher das Ereignis stammt.

Im SimpleManipulationDemo-Programm werden die Eigenschaften „Source“ und „OriginalSource“ auf das Bildelement eingestellt, das die Manipulationsereignisse generiert. Nur ein Element, bei dem die Eigenschaft „IsManipulationEnable“ auf „True“ eingestellt ist, wird in diesen Manipulationsereignissen als Source- und OriginalSource-Eigenschaft angezeigt.

Darüber hinaus enthält jede der Ereignisargumentklassen, die mit den Manipulationsereignissen verknüpft sind, eine Eigenschaft mit der Bezeichnung „ManipulationContainer“. Hierbei handelt es sich um das Element, innerhalb dessen die Multitouch-Manipulation auftritt. Alle Koordinaten in den Manipulationsereignissen beziehen sich auf diesen Container.

Standardmäßig ist die Eigenschaft „ManipulationContainer“ auf das gleiche Element wie die Eigenschaft „Source“ und „OriginalSource“ eingestellt – das Element, das manipuliert wird. Dies ist jedoch möglicherweise nicht die gewünschte Einstellung. Im Allgemeinen soll der Manipulationscontainer nicht mit dem zu manipulierenden Element identisch sein, da komplizierte Interaktionen die dynamische Bewegung, Skalierung und Drehung des gleichen Elements, das die Berührungsinformationen meldet, beeinflussen. Stattdessen soll der Manipulationscontainer ein übergeordnetes Element des manipulierten Elements oder eventuell ein höher angeordnetes Element in der visuellen Struktur sein.

Bei den meisten Manipulationsereignissen ist die Eigenschaft „ManipulationContainer“ nur abrufbar. Die Ausnahme stellt das allererste Manipulationsereignis dar, das ein Element empfängt. Im Ereignis „ManipulationStarting“ können Sie die Eigenschaft „ManipulationContainer“ in eine passendere Eigenschaft ändern. Im SimpleManipulationDemo-Projekt handelt es sich bei dieser Aufgabe um eine einzelne Codezeile:

args.ManipulationContainer = this;

Bei allen nachfolgenden Ereignissen ist die Eigenschaft „ManipulationContainer“ dann das MainWindow-Element und nicht das Bildelement. Alle Koordinaten beziehen sich auf dieses Fenster. Dies funktioniert problemlos, da das Raster mit den Bildelementen ebenfalls mit dem Fenster ausgerichtet wird.

Der übrige Teil der Methode „OnManipulationStarting“ dient dazu, das berührte Bildelement in den Vordergrund zu stellen, indem die angefügte Eigenschaft „Panel.ZIndex“ aller Bildelemente im Raster zurückgesetzt wird. Dies ist eine einfache Möglichkeit zur Verarbeitung von ZIndex, jedoch wahrscheinlich die optimale, da sie zu plötzlichen Änderungen führt.

Ereignisse „ManipulationDelta“ und „DeltaManipulation“

Als weiteres Ereignis wird nur noch das Ereignis „ManipulationDelta“ im SimpleManpulationDemo-Projekt verarbeitet. In der Klasse „ManipulationDeltaEventArgs“ werden zwei Eigenschaften des Typs „ManipulationDelta“ unterschieden. (Genau, das Ereignis und die Klasse weisen denselben Namen auf.) Es handelt sich hierbei um die Eigenschaften „DeltaManipulation“ und „CumulativeManipulation“. Wie die Namen bereits vermuten lassen, spiegelt „DeltaManipulation“ die Manipulation seit dem letzten ManipulationDelta-Ereignis wider und „CumulativeManipulation“ die vollständige Manipulation, die mit dem Ereignis „ManipulationStarting“ begonnen hat.

„ManipulationDelta“ verfügt über vier Eigenschaften:

  • Übersetzung des Typs „Vector“
  • Skalierung des Typs „Vector“
  • Erweiterung des Typs „Vector“
  • Drehung des Typs „double“

Die Vektorstruktur definiert zwei Eigenschaften mit der Bezeichnung „X“ und „Y“ des Typs „double“. Eine der bedeutenderen Unterschiede hinsichtlich der Manipulationsunterstützung unter Silverlight für Windows Phone 7 besteht darin, dass die Eigenschaften „Expansion“ und „Rotation“ fehlen.

Die Eigenschaft „Translation“ deutet eine horizontale und vertikale Bewegung (oder Schwenken) an. Die Berührung eines Elements mit nur einem Finger kann Änderungen in der Übersetzung hervorrufen, die Übersetzung kann jedoch auch ein Teil anderer Manipulationen sein.

Die Eigenschaften „Scale“ und „Expansion“ können auf eine Größenänderung (Zoom) hinweisen, die stets eine Berührung mit zwei Fingern erfordert. Die Skalierung wird mittels Multiplikation und die Erweiterung mittels Addition berechnet. Verwenden Sie die Eigenschaft „Scale“ zum Festlegen einer Größenumwandlung und die Eigenschaft „Expansion“ zum Erhöhen oder Verringern der Eigenschaften „Width“ und „Height“ für ein Element nach geräteunabhängigen Einheiten.

In WPF 4.0 sind die X- und Y-Werte des Skalierungsvektors stets identisch. Die Manipulationsereignisse enthalten nicht genügend Informationen zur anisotropen Skalierung eines Elements (d. h. unterschiedliche horizontale und vertikale Richtung).

Die Eigenschaft „Rotation“ erfordert standardmäßig auch die Berührung mit zwei Fingern, obwohl Sie später noch erfahren werden, wie Sie Drehungen mit nur einem Finger aktivieren können. Bei bestimmten ManipulationDelta-Ereignissen können alle vier Eigenschaften festgelegt werden. Es können zwei Finger zum Vergrößern eines Elements verwendet werden, wobei es gleichzeitig gedreht und an eine andere Position verschoben werden kann.

Die Skalierung und Drehung beziehen sich stets auf einen bestimmten Mittelpunkt. Dieser Mittelpunkt steht auch im Ereignisargument „ManipulationDeltaEventArgs“ in der Eigenschaft „ManipulationOrigin“ des Typs „Point“ zur Verfügung. Dieser Ursprung bezieht sich auf die im Ereignis „ManipulationStarting“ festgelegte Eigenschaft „ManipulationContainer“.

Ihre Aufgabe beim ManipulationDelta-Ereignis besteht darin, die Eigenschaft „RenderTransform“ des manipulierten Objekts in Übereinstimmung mit den Delta-Werten in der folgenden Reihenfolge zu ändern: Zuerst skalieren, dann drehen und zum Abschluss übersetzen. (Da die horizontalen und vertikalen Skalierungsfaktoren eigentlich identisch sind, können Sie die Reihenfolge der Skalierungs- und Drehungstransformationen tauschen und dennoch dasselbe Ergebnis erzielen.)

Die Methode „OnManipulationDelta“ in Abbildung 3 zeigt einen Standardansatz. Das Matrix-Objekt wird von der Eigenschaft „MatrixTransform“ erzielt, die für das manipulierte Bildelement festgelegt wurde. Die Modifikation erfolgt über Aufrufe an „ScaleAt“ und „RotateAt“ (beide beziehen sich auf die Eigenschaft „ManipulationOrigin“) sowie an „Translate“. Die Matrix ist vielmehr eine Struktur als eine Klasse. Daher müssen Sie die Verfahren abschließen, indem Sie den alten Wert in der Eigenschaft „MatrixTransform“ durch einen neuen Wert ersetzen.

Es ist möglich, diesen Code leicht zu variieren. Wie gezeigt, kann der Code mit dieser Anweisung um einen Mittelpunkt skaliert werden:

matrix.ScaleAt(delta.Scale.X, delta.Scale.Y, center.X, center.Y);

Dies entspricht den folgenden Schritten: Übersetzung zum negativen Wert des Mittelpunkts, Skalierung und dann Rückübersetzung:

matrix.Translate(-center.X, -center.Y);
matrix.Scale(delta.Scale.X, delta.Scale.Y);
matrix.Translate(center.X, center.Y);

Die Methode „RotateAt“ kann auch durch Folgendes ersetzt werden:

matrix.Translate(-center.X, -center.Y);
matrix.Rotate(delta.Rotation);
matrix.Translate(center.X, center.Y);

Die zwei benachbarten Translate-Aufrufe heben sich nun gegenseitig auf, daher lautet die Zusammensetzung wie folgt:

matrix.Translate(-center.X, -center.Y);
matrix.Scale(delta.Scale.X, delta.Scale.Y);
matrix.Rotate(delta.Rotation);
matrix.Translate(center.X, center.Y);

Dies erweist sich möglicherweise als etwas effizienter.

In Abbildung 4 wird das SimpleManipulationDemo-Projekt in Aktion dargestellt.

Figure 4 The SimpleManipulationDemo Program

Abbildung 4 Das SimpleManipulationDemo-Programm

Aktivieren des Containers?

Im SimpleManpulationDemo-Programm steht eine interessante Funktion zur Verfügung, mit der Sie gleichzeitig zwei oder sogar noch mehr Bildelemente manipulieren können, sofern Sie über den entsprechenden Hardwaresupport verfügen und genügend Finger einsetzen können. Jedes Bildelement erzeugt sein eigenes ManipulationStarting-Ereignis und seine eigene Reihe von ManipulationDelta-Ereignissen. Anhand der Eigenschaft „Source“ der Ereignisargumente unterscheidet der Code effektiv zwischen mehreren Bildelementen.

Daher ist es wichtig, keine Statusinformationen in die Felder einzugeben, die besagen, dass nur jeweils ein Element manipuliert werden kann.

Es ist möglich, mehrere Elemente gleichzeitig zu manipulieren, da für jedes der Bildelemente die Eigenschaft „IsManipulationEnable“ auf „True“ eingestellt ist. Jedes Bildelement kann eine eindeutige Reihe von Manipulationsereignissen generieren.

Wenn Sie sich zum ersten Mal mit diesen Manipulationsereignissen beschäftigen, stellen Sie stattdessen einfach die Eigenschaft „IsManpulationEnabled“ nur in der MainWindow-Klasse oder für andere, als Elemente dienende Container auf „True“ ein. Dies ist möglich, in der Praxis jedoch etwas umständlicher und nicht unbedingt so leistungsfähig. Der einzige echte Vorteil besteht darin, dass Sie die Eigenschaft „ManipulationContainer“im Ereignis „ManipulationStarting“ nicht festlegen müssen. Später wird es noch unübersichtlicher, wenn Sie feststellen müssen, welches Element manipuliert wird. Hierzu müssen Sie mittels der Eigenschaft „ManipulationOrigin“ des ManipulatedStarted-Ereignisses einen Treffertest für die untergeordneten Elemente ausführen.

Anschließend müssen Sie das manipulierte Element als Feld zur Verwendung für zukünftige ManipulationDelta-Ereignisse speichern. In diesem Fall können Statusinformationen in den Feldern gespeichert werden, da Sie nur jeweils ein Element im Container manipulieren können.

Der Manipulationsmodus

Wie Sie gesehen haben, ist eine der wichtigen Eigenschaften, die während des ManipulationStarting-Ereignisses festzulegen sind, die Eigenschaft „ManipulationContainer“. Es gibt noch weitere nützliche Eigenschaften zur benutzerdefinierten Anpassung dieser bestimmten Manipulation.

Sie können die ausführbaren Manipulationsarten einschränken, indem Sie die Eigenschaft „Mode“ mit einem Element der ManipulationModes-Auflistung initialisieren. Wenn Sie zum Beispiel die Manipulation ausschließlich für einen horizontalen Bildlauf verwenden, müssen Sie die Ereignisse einfach auf eine horizontale Übersetzung einschränken. Das ManipulationModesDemo-Programm ermöglicht die dynamische Einstellung des Modus durch die Anzeige einer Liste mit RadioButton-Elementen, in der die Optionen aufgeführt werden, wie in Abbildung 5 dargestellt.

Figure 5 The ManipulationModeDemo Display

Abbildung 5 Die ManipulationModeDemo-Anzeige

Das RadioButton-Element ist natürlich nur eines der vielen Steuerelemente in WPF 4.0, die direkt auf Berührungen reagieren.

Die Drehung mit nur einem Finger

Standardmäßig benötigen Sie zwei Finger zum Drehen eines Objekts. Wenn sich jedoch ein echtes Foto auf einem Tisch befindet, können Sie Ihren Finger auf die Kante legen und das Foto im Kreis drehen. Die Drehung erfolgt im Wesentlichen um den Mittelpunkt des Objekts.

Auf diese Weise können Sie auch bei den Manipulationsereignissen vorgehen. Stellen Sie hierzu die Eigenschaft „Pivot“ des Ereignisarguments „ManipulationStartingEventArgs“ ein. Standardmäßig beträgt die Eigenschaft „Pivot“ Null. Sie können die Drehung mit einem Finger durch Einstellen der Eigenschaft auf ein ManipulationPivot-Objekt aktivieren. Die wichtigste Eigenschaft von
„ManipulationPivot“ lautet „Center“, die Sie als Mittelpunkt des manipulierten Elements berechnen sollten:

Point center = new Point(element.ActualWidth / 2, 
                         element.ActualHeight / 2);

Dieser Mittelpunkt muss sich jedoch auf den Manipulationscontainer beziehen, wobei es sich in den Programmen, die ich Ihnen vorgestellt habe, um das Element handelt, das die Ereignisse verarbeitet. Die Übersetzung dieses Mittelpunkts vom manipulierten Element zum Container ist einfach:

center = element.TranslatePoint(center, this);

Es müssen ebenfalls weitere Informationen angegeben werden. Falls Sie nur einen Mittelpunkt festlegen, tritt ein Problem auf, wenn Sie Ihren Finger genau in der Mitte des Elements positionieren: Eine kleine Bewegung führt schon dazu, dass das Element wie wild herumwirbelt! Aus diesem Grund weist das ManipulationPivot-Objekt auch eine Radius-Eigenschaft auf. Die Drehung erfolgt nicht, wenn sich der Finger innerhalb der Radius-Einheiten des Mittelpunkts befindet. Das ManipulationPivotDemo-Programm stellt diesen Radius auf 1,27 cm (0,5 Zoll) ein:

args.Pivot = new ManipulationPivot(center, 48);

Nun kann mit nur einem Finger gleichzeitig eine Drehung und eine Übersetzung ausgeführt werden.

Über die Grundlagen hinaus

In diesem Artikel haben Sie die Grundlagen zur Verwendung der Manipulationsereignisse in WPF 4.0 kennen gelernt. Es gibt natürlich einige Varianten dieser Techniken, auf die ich in zukünftigen Artikeln näher eingehen werde. Dann werde ich auch die Leistung bei der Manipulation der Trägheit erörtern.

Sehen Sie sich auch die Surface Toolkit for Windows Touch an, die Touch-optimierte Steuerelemente für Ihre Anwendungen bietet. Durch Verwendung des ScatterView-Steuerelements insbesondere müssen die Manipulationsereignisse nicht mehr direkt für grundlegende Aufgaben wie das Manipulieren von Fotos eingesetzt werden. Dieses Steuerelement weist einige moderne Effekte und Verhaltensweisen auf, die dafür sorgen, dass sich Ihre Anwendung genauso verhält wie andere Touch-Anwendungen.

Charles Petzold schreibt seit langem redaktionelle Beiträge für das MSDN Magazin. Zurzeit schreibt er den Artikel „Programming Windows Phone 7“, der als kostenloses, herunterladbares E-Book im Herbst 2010 veröffentlicht wird. Eine Vorschau-Edition ist derzeit auf seiner Website charlespetzold.com verfügbar.

Unser Dank gilt den folgenden technischen Experten für die Durchsicht dieses Artikels: Doug Kramer, Robert Levy und Anson Tsao