Udostępnij za pośrednictwem


Przewodnik: tworzenie pierwszej aplikacji dotykowej

WPF umożliwia aplikacjom reagowanie na dotyk. Na przykład można wchodzić w interakcję z aplikacją za pomocą jednego lub kilku palców na urządzeniu z uwzględnieniem dotyku, na przykład ekranu dotykowego Ten przewodnik tworzy aplikację, która umożliwia użytkownikowi przenoszenie, zmienianie rozmiaru lub obracanie pojedynczego obiektu za pomocą dotyku.

Warunki wstępne

Do ukończenia tego przewodnika potrzebne są następujące składniki:

  • Visual Studio.

  • Urządzenie, które akceptuje dotykowe dane wejściowe, takie jak ekran dotykowy, który obsługuje funkcję Windows Touch.

Ponadto musisz mieć podstawową wiedzę na temat tworzenia aplikacji w WPF, szczególnie sposobu subskrybowania i obsługi zdarzenia. Aby uzyskać więcej informacji, zobacz Walkthrough: My first WPF desktop application.

Tworzenie aplikacji

Aby utworzyć aplikację

  1. Utwórz nowy projekt aplikacji WPF w Visual Basic lub Visual C# o nazwie BasicManipulation. Aby uzyskać więcej informacji, zobacz Walkthrough: My first WPF desktop application.

  2. Zastąp zawartość pliku MainWindow.xaml następującym kodem XAML.

    Ten znacznik tworzy prostą aplikację zawierającą czerwony Rectangle na Canvas. Właściwość IsManipulationEnabled obiektu Rectangle jest ustawiona na wartość true, aby mogła obsługiwać zdarzenia manipulacji. Aplikacja subskrybuje zdarzenia ManipulationStarting, ManipulationDeltai ManipulationInertiaStarting. Te zdarzenia zawierają logikę przenoszenia Rectangle podczas manipulowania nim przez użytkownika.

    <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. Jeśli używasz języka Visual Basic, w pierwszym wierszu pliku MainWindow.xaml zastąp x:Class="BasicManipulation.MainWindow" ciągiem x:Class="MainWindow".

  4. W klasie MainWindow dodaj następującą procedurę obsługi zdarzeń ManipulationStarting.

    Zdarzenie ManipulationStarting występuje, gdy WPF wykrywa, że dotyk zaczyna manipulować obiektem. Kod określa, że pozycja manipulacji powinna być względem Window poprzez ustawienie właściwości ManipulationContainer.

    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. W klasie MainWindow dodaj następującą procedurę obsługi zdarzeń ManipulationDelta.

    Zdarzenie ManipulationDelta występuje, gdy wejście dotykowe zmienia położenie i może wystąpić wiele razy podczas manipulowania. Zdarzenie może również wystąpić po podniesieniu palca. Jeśli na przykład użytkownik przeciąga palcem przez ekran, zdarzenie ManipulationDelta występuje wiele razy, gdy palec porusza się. Gdy użytkownik podnosi palec z ekranu, zdarzenie ManipulationDelta nadal występuje w celu symulowania inercji.

    Kod stosuje DeltaManipulation do RenderTransformRectangle, aby przesunąć Rectangle, gdy użytkownik porusza danymi wejściowymi dotykowymi. Sprawdza również, czy Rectangle znajduje się poza granicami Window, gdy zdarzenie występuje podczas inercji. Jeśli tak, aplikacja wywołuje metodę ManipulationDeltaEventArgs.Complete, aby zakończyć manipulowanie.

    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. W klasie MainWindow dodaj następującą procedurę obsługi zdarzeń ManipulationInertiaStarting.

    Zdarzenie ManipulationInertiaStarting występuje, gdy użytkownik podnosi wszystkie palce z ekranu. Kod ustawia początkową szybkość i zwalnianie ruchu, rozszerzania i obrotu prostokąta.

    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. Skompiluj i uruchom projekt.

    W oknie powinien zostać wyświetlony czerwony kwadrat.

Testowanie aplikacji

Aby przetestować aplikację, spróbuj wykonać następujące czynności. Należy pamiętać, że w tym samym czasie można wykonać więcej niż jedną z następujących czynności.

  • Aby przenieść Rectangle, umieść palec na Rectangle i przesuń palcem po ekranie.

  • Aby zmienić rozmiar Rectangle, umieść dwa palce na Rectangle i przesuń palce bliżej lub dalej od siebie.

  • Aby obrócić Rectangle, umieść dwa palce na Rectangle i obróć palce wokół siebie.

Aby spowodować bezwładność, szybko podnieś palce z ekranu podczas wykonywania poprzednich manipulacji. Obiekt Rectangle będzie się nadal przemieszczać, zmieniać rozmiar lub obracać przez kilka sekund, zanim się zatrzyma.

Zobacz też