Exemplarische Vorgehensweise: Erstellen der ersten Fingereingabeanwendung

WPF ermöglicht Anwendungen, auf Toucheingaben zu reagieren. Sie können beispielsweise mit einer Anwendung interagieren, indem Sie einen oder mehrere Finger auf einem berührungsempfindlichen Gerät (z. B. einem Touchscreen) verwenden. In dieser exemplarischen Vorgehensweise wird eine Anwendung erstellt, die es dem Benutzer ermöglicht, ein einzelnes Objekt durch Berührung zu bewegen, in der Größe zu verändern oder zu drehen.

Voraussetzungen

Zum Abschließen dieser exemplarischen Vorgehensweise benötigen Sie Folgendes:

  • Visual Studio.

  • Ein Gerät, das Toucheingaben akzeptiert (z. B. ein Touchscreen) und Windows Touch unterstützt.

Außerdem sollten Sie ein Grundverständnis dafür haben, wie eine Anwendung in WPF erstellt wird, insbesondere wie ein Ereignis abonniert und verarbeitet wird. Weitere Informationen finden Sie unter Exemplarische Vorgehensweise: Meine erste WPF-Desktopanwendung.

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 Exemplarische Vorgehensweise: Meine erste WPF-Desktopanwendung.

  2. Ersetzen Sie den Inhalt von „MainWindow.xaml“ durch den folgenden XAML-Code.

    Dieses Markup erstellt eine einfache Anwendung, die ein rotes Rectangle für ein Canvas-Element enthält. Die IsManipulationEnabled-Eigenschaft von Rectangle ist auf TRUE festgelegt, sodass es Bearbeitungsereignisse empfängt. Die Anwendung abonniert die ManipulationStarting-, ManipulationDelta- und ManipulationInertiaStarting-Ereignisse. Diese Ereignisse enthalten die Logik, um das Rectangle zu verschieben, wenn es durch den Benutzer bearbeitet wird.

    <Window x:Class="BasicManipulation.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://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. Wenn Sie Visual Basic verwenden, ersetzen Sie x:Class="BasicManipulation.MainWindow" in der ersten Zeile von „MainWindow.xaml“ durch x:Class="MainWindow".

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

    Das ManipulationStarting-Ereignis tritt auf, wenn WPF erkennt, dass Toucheingabe verwendet wird, um ein Objekt zu bearbeiten. Der Code gibt an, dass die Position der Bearbeitung relativ zum Window sein soll, indem die ManipulationContainer-Eigenschaft festgelegt wird.

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

    Das ManipulationDelta-Ereignis tritt auf, wenn die Toucheingabe die Position ändert. Dies kann während der Bearbeitung mehrmals auftreten. Das Ereignis kann auch auftreten, nachdem ein Finger gelöst wurde. Wenn der Benutzer beispielsweise einen Finger über einen Bildschirm zieht, tritt das ManipulationDelta-Ereignis mehrmals auf, wenn sich der Finger bewegt. Wenn der Benutzer einen Finger vom Bildschirm löst, tritt das ManipulationDelta-Ereignis wiederholt auf, um Untätigkeit zu simulieren.

    Der Code wendet DeltaManipulation auf RenderTransform des Rectangle an, um es zu bewegen, wenn der Benutzer die Bewegung über die Toucheingabe vorgibt. Außerdem wird überprüft, ob sich das Rectangle außerhalb der Grenzen des Window befindet, wenn das Ereignis während der Untätigkeit auftritt. Ist dies der Fall, ruft die Anwendung die ManipulationDeltaEventArgs.Complete-Methode auf, um die Bearbeitung zu beenden.

    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;
    }
    
    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
    
  6. Fügen Sie in der MainWindow-Klasse den folgenden ManipulationInertiaStarting-Ereignishandler hinzu.

    Das ManipulationInertiaStarting-Ereignis tritt auf, wenn der Benutzer alle Finger vom Bildschirm löst. Der Code legt die Anfangsgeschwindigkeit und die Verzögerung für die Bewegung, Größenänderung und Drehung des Rechtecks fest.

    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;
    }
    
    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
    
  7. Erstellen Sie das Projekt, und führen Sie es aus.

    Es sollte ein rotes Quadrat im Fenster angezeigt werden.

Testen der Anwendung

Um die Anwendung zu testen, probieren Sie die folgenden Bearbeitungen aus. Beachten Sie, dass Sie mehrere der folgenden Aktionen 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 aufeinander zu oder voneinander weg.

  • Um die das Rectangle zu drehen, legen Sie zwei Finger auf das Rectangle und drehen die Finger umeinander.

Um den Ruhezustand herbeizuführen, lösen Sie Ihre Finger schnell vom Bildschirm, während Sie die oben genannten Bearbeitungen durchführen. Das Rectangle bewegt sich einige Sekunden lang weiter, ändert die Größe oder dreht sich, bevor es angehalten wird.

Weitere Informationen