Exemplarische Vorgehensweise: Erstellen der ersten Fingereingabeanwendung

WPF ermöglicht es Anwendungen, auf Fingereingabe zu reagieren. Sie können z. B. mit einer Anwendung über einen oder mehrere Finger auf einem Gerät mit Berührungseingabe, z. B. einem Touchscreen, interagieren. In dieser exemplarischen Vorgehensweise wird eine Anwendung erstellt, die es dem Benutzer ermöglicht, ein Objekt per Fingereingabe zu verschieben, seine Größe zu ändern oder es zu drehen.

Voraussetzungen

Zum Durchführen dieser exemplarischen Vorgehensweise benötigen Sie die folgenden Komponenten:

  • Microsoft Visual Studio 2010.

  • Windows 7.

  • Ein Gerät, das Fingereingabe akzeptiert, z. B. ein Touchscreen mit Windows Touch-Unterstützung.

Darüber hinaus sollten Sie über Grundkenntnisse zum Erstellen einer Anwendung in WPF verfügen, insbesondere zum Abonnieren und Verarbeiten eines Ereignisses. Weitere Informationen finden Sie unter Exemplarische Vorgehensweise: Erste Schritte mit WPF.

Erstellen der Anwendung

So erstellen Sie die Anwendung

  1. Erstellen Sie ein neues WPF-Anwendungsprojekt in Visual Basic oder Visual C# mit dem Namen BasicManipulation. Weitere Informationen finden Sie unter Gewusst wie: Erstellen eines neuen WPF-Anwendungsprojekts.

  2. Ersetzen Sie den Inhalt der Datei MainWindow.xaml durch folgende XAML.

    Dieses Markup erstellt eine einfache Anwendung, die auf einem Canvas ein rotes Rectangle enthält. Die IsManipulationEnabled-Eigenschaft des Rectangle wird auf true festgelegt, sodass es Manipulationsereignisse empfängt. Die Anwendung abonniert die Ereignisse ManipulationStarting, ManipulationDelta und ManipulationInertiaStarting. Diese Ereignisse enthalten die Logik, um das Rectangle zu verschieben, wenn der Benutzer es bearbeitet.

    <Window x:Class="BasicManipulation.MainWindow"
            xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
            Title="Move, Size, and Rotate the Square"
            WindowState="Maximized"
            ManipulationStarting="Window_ManipulationStarting"
            ManipulationDelta="Window_ManipulationDelta"
            ManipulationInertiaStarting="Window_InertiaStarting">
      <Window.Resources>
    
        <!--The movement, rotation, and size of the Rectangle is 
            specified by its RenderTransform.-->
        <MatrixTransform x:Key="InitialMatrixTransform">
          <MatrixTransform.Matrix>
            <Matrix OffsetX="200" OffsetY="200"/>
          </MatrixTransform.Matrix>
        </MatrixTransform>
    
      </Window.Resources>
    
      <Canvas>
        <Rectangle Fill="Red" Name="manRect"
                     Width="200" Height="200" 
                     RenderTransform="{StaticResource InitialMatrixTransform}"
                     IsManipulationEnabled="true" />
      </Canvas>
    </Window>
    
    
  3. Ersetzen Sie bei Verwendung von Visual Basic in der ersten Zeile von "MainWindow.xaml" den Code x:Class="BasicManipulation.MainWindow" durch x:Class="MainWindow".

  4. Fügen Sie in der MainWindow-Klasse den folgenden ManipulationStarting-Ereignishandler hinzu.

    Das ManipulationStarting-Ereignis tritt ein, wenn WPF erkennt, dass die Fingereingabe beginnt, ein Objekt zu bearbeiten. Der Code gibt an, dass die Position der Manipulation relativ zum Window sein sollte, indem er die ManipulationContainer-Eigenschaft festlegt.

    Private Sub Window_ManipulationStarting(ByVal sender As Object, ByVal e As ManipulationStartingEventArgs)
        e.ManipulationContainer = Me
        e.Handled = True
    End Sub
    
    void Window_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
    {
        e.ManipulationContainer = this;
        e.Handled = true;
    }
    
  5. Fügen Sie in der MainWindow-Klasse den folgenden ManipulationDelta-Ereignishandler hinzu.

    Das ManipulationDelta-Ereignis tritt ein, wenn die Fingereingabe die Position ändert. Es kann mehrmals während einer Manipulation auftreten. Das Ereignis kann auch eintreten, nachdem ein Finger angehoben wurde. Wenn der Benutzer z. B. einen Finger über einen Bildschirm zieht, tritt das ManipulationDelta-Ereignis mehrmals ein, wenn sich der Finger bewegt. Wenn der Benutzer einen Finger vom Bildschirm hebt, tritt das ManipulationDelta-Ereignis weiterhin ein, um Trägheit zu simulieren.

    Der Code wendet die DeltaManipulation auf die RenderTransform des Rectangle an, um es zu verschieben, wenn der Benutzer die Fingereingabe verschiebt. Er überprüft auch, ob sich das Rectangle außerhalb der Grenzen des Window befindet, wenn das Ereignis während der Trägheit auftritt. In diesem Fall ruft die Anwendung die ManipulationDeltaEventArgs.Complete-Methode auf, um die Manipulation zu beenden.

    Private Sub Window_ManipulationDelta(ByVal sender As Object, ByVal e As ManipulationDeltaEventArgs)
    
        ' Get the Rectangle and its RenderTransform matrix.
        Dim rectToMove As Rectangle = e.OriginalSource
        Dim rectTransform As MatrixTransform = rectToMove.RenderTransform
        Dim rectsMatrix As Matrix = rectTransform.Matrix
    
    
        ' Rotate the shape
        rectsMatrix.RotateAt(e.DeltaManipulation.Rotation,
                             e.ManipulationOrigin.X,
                             e.ManipulationOrigin.Y)
    
        ' Resize the Rectangle. Keep it square 
        ' so use only the X value of Scale.
        rectsMatrix.ScaleAt(e.DeltaManipulation.Scale.X,
                            e.DeltaManipulation.Scale.X,
                            e.ManipulationOrigin.X,
                            e.ManipulationOrigin.Y)
    
        'move the center
        rectsMatrix.Translate(e.DeltaManipulation.Translation.X,
                              e.DeltaManipulation.Translation.Y)
    
        ' Apply the changes to the Rectangle.
        rectTransform = New MatrixTransform(rectsMatrix)
        rectToMove.RenderTransform = rectTransform
    
        Dim container As FrameworkElement = e.ManipulationContainer
        Dim containingRect As New Rect(container.RenderSize)
    
        Dim shapeBounds As Rect = rectTransform.TransformBounds(
                                    New Rect(rectToMove.RenderSize))
    
        ' Check if the rectangle is completely in the window.
        ' If it is not and intertia is occuring, stop the manipulation.
        If e.IsInertial AndAlso Not containingRect.Contains(shapeBounds) Then
            e.Complete()
        End If
    
        e.Handled = True
    End Sub
    
    void Window_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
    {
    
        // Get the Rectangle and its RenderTransform matrix.
        Rectangle rectToMove = e.OriginalSource as Rectangle;
        Matrix rectsMatrix = ((MatrixTransform)rectToMove.RenderTransform).Matrix;
    
        // Rotate the Rectangle.
        rectsMatrix.RotateAt(e.DeltaManipulation.Rotation, 
                             e.ManipulationOrigin.X, 
                             e.ManipulationOrigin.Y);
    
        // Resize the Rectangle.  Keep it square 
        // so use only the X value of Scale.
        rectsMatrix.ScaleAt(e.DeltaManipulation.Scale.X, 
                            e.DeltaManipulation.Scale.X, 
                            e.ManipulationOrigin.X,
                            e.ManipulationOrigin.Y);
    
        // Move the Rectangle.
        rectsMatrix.Translate(e.DeltaManipulation.Translation.X,
                              e.DeltaManipulation.Translation.Y);
    
        // Apply the changes to the Rectangle.
        rectToMove.RenderTransform = new MatrixTransform(rectsMatrix);
    
        Rect containingRect =
            new Rect(((FrameworkElement)e.ManipulationContainer).RenderSize);
    
        Rect shapeBounds =
            rectToMove.RenderTransform.TransformBounds(
                new Rect(rectToMove.RenderSize));
    
        // Check if the rectangle is completely in the window.
        // If it is not and intertia is occuring, stop the manipulation.
        if (e.IsInertial && !containingRect.Contains(shapeBounds))
        {
            e.Complete();
        }
    
    
        e.Handled = true;
    }
    
  6. Fügen Sie in der MainWindow-Klasse den folgenden ManipulationInertiaStarting-Ereignishandler hinzu.

    Das ManipulationInertiaStarting-Ereignis tritt ein, wenn der Benutzer alle Finger vom Bildschirm hebt. Der Code legt die anfängliche Geschwindigkeit und die Verzögerung für Bewegung, Erweiterung und Drehung des Rechtecks fest.

    Private Sub Window_InertiaStarting(ByVal sender As Object,
                                       ByVal e As ManipulationInertiaStartingEventArgs)
    
        ' Decrease the velocity of the Rectangle's movement by 
        ' 10 inches per second every second.
        ' (10 inches * 96 pixels per inch / 1000ms^2)
        e.TranslationBehavior.DesiredDeceleration = 10.0 * 96.0 / (1000.0 * 1000.0)
    
        ' Decrease the velocity of the Rectangle's resizing by 
        ' 0.1 inches per second every second.
        ' (0.1 inches * 96 pixels per inch / (1000ms^2)
        e.ExpansionBehavior.DesiredDeceleration = 0.1 * 96 / (1000.0 * 1000.0)
    
        ' Decrease the velocity of the Rectangle's rotation rate by 
        ' 2 rotations per second every second.
        ' (2 * 360 degrees / (1000ms^2)
        e.RotationBehavior.DesiredDeceleration = 720 / (1000.0 * 1000.0)
    
        e.Handled = True
    End Sub
    
    void Window_InertiaStarting(object sender, ManipulationInertiaStartingEventArgs e)
    {
    
        // Decrease the velocity of the Rectangle's movement by 
        // 10 inches per second every second.
        // (10 inches * 96 pixels per inch / 1000ms^2)
        e.TranslationBehavior.DesiredDeceleration = 10.0 * 96.0 / (1000.0 * 1000.0);
    
        // Decrease the velocity of the Rectangle's resizing by 
        // 0.1 inches per second every second.
        // (0.1 inches * 96 pixels per inch / (1000ms^2)
        e.ExpansionBehavior.DesiredDeceleration = 0.1 * 96 / (1000.0 * 1000.0);
    
        // Decrease the velocity of the Rectangle's rotation rate by 
        // 2 rotations per second every second.
        // (2 * 360 degrees / (1000ms^2)
        e.RotationBehavior.DesiredDeceleration = 720 / (1000.0 * 1000.0);
    
        e.Handled = true;
    }
    
  7. Erstellen Sie das Projekt, und führen Sie es aus.

    Sie sollten sehen, dass ein rotes Quadrat im Fenster angezeigt wird.

Testen der Anwendung

Probieren Sie zum Testen der Anwendung die folgenden Manipulationen aus. Beachten Sie, dass Sie mehrere der folgenden Schritte gleichzeitig ausführen können.

  • Um das Rectangle zu verschieben, legen Sie einen Finger auf das Rectangle, und bewegen Sie den Finger über den Bildschirm.

  • Um die Größe des Rectangle zu ändern, legen Sie zwei Finger auf das Rectangle, und bewegen Sie die Finger näher zusammen oder weiter auseinander.

  • Um das Rectangle zu drehen, legen Sie zwei Finger auf das Rectangle, und drehen Sie die Finger um den jeweils anderen Finger.

Um Trägheit zu verursachen, lösen Sie die Finger schnell vom Bildschirm, während Sie die vorherigen Manipulationen ausführen. Das Rectangle wird für einige Sekunden weiter verschoben, in der Größe verändert oder gedreht.

Siehe auch

Referenz

UIElement.ManipulationStarting

UIElement.ManipulationDelta

UIElement.ManipulationInertiaStarting