Пошаговое руководство. Создание первого приложения для обработки касаний

WPF позволяет приложениям реагировать на сенсорный ввод. Например, можно взаимодействовать с приложением, используя пальцы на экране, чувствительном к касаниям, например на сенсорном экране. В данном пошаговом руководстве создается приложение, которое позволяет пользователям перемещать, изменять размеры и выполнять циклический сдвиг одного объекта с использованием касания.

Предварительные требования

Ниже приведены компоненты, необходимые для выполнения данного пошагового руководства.

  • Microsoft Visual Studio 2010.

  • Windows 7.

  • Устройство, принимающее сенсорный ввод, например сенсорный экран с поддержкой технологии касания Windows.

Кроме того, необходимо иметь базовое понимание процесса создания приложения в WPF, особенно такие его аспекты, как подписывание и обработка события. Дополнительные сведения см. в разделе Пошаговое руководство. Начало работы с WPF.

Создание приложения

Чтобы создать приложение

  1. Создайте в Visual Basic или Visual C# новый проект приложения WPF с именем BasicManipulation. Дополнительные сведения см. в разделе Практическое руководство. Создание нового проекта приложения WPF.

  2. Замените содержимое файла MainWindow.xaml следующим XAML.

    Разметка создает простое приложение, содержащее красный прямоугольник Rectangle на канве Canvas. Свойство IsManipulationEnabled этого объекта Rectangle установлено в значение "true", так что он будет получать события манипулирования. Приложение подписывается на события ManipulationStarting, ManipulationDelta и ManipulationInertiaStarting. Эти события содержат логику перемещения объекта Rectangle, когда пользователь им манипулирует.

    <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. Если используется Visual Basic, замените x:Class="BasicManipulation.MainWindow" в первой строке файла MainWindow.xaml на x:Class="MainWindow".

  4. В класс MainWindow добавьте следующий обработчик событий ManipulationStarting.

    Событие ManipulationStarting возникает, когда WPF обнаруживает, что сенсорный ввод начал манипулирование объектом. Этот код задает, что положение манипуляции должно быть относительно Window, путем установки свойства ManipulationContainer.

    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. В класс MainWindow добавьте следующий обработчик событий ManipulationDelta.

    Событие ManipulationDelta возникает, когда сенсорный ввод изменяет положение, и может возникать несколько раз в течение манипуляции. Это событие также может возникать после отрыва пальца от экрана. Например, если пользователь перемещает палец по экрану, событие ManipulationDelta возникает несколько раз за время перемещения пальца. Когда пользователь отрывает палец от экрана, событие ManipulationDelta продолжает возникать для имитации инерции.

    Этот код применяет свойство DeltaManipulation к свойству RenderTransform объекта Rectangle, чтобы перемещать его, как пользователь перемещает сенсорный ввод. Он также выполняет проверку, не находится ли объект Rectangle за пределами границ окна Window, когда событие возникает вследствие инерции. Если это так, то приложение вызывает метод [имеетзначениеM:System.Windows.Input.ManipulationDeltaEventArgs.Complete], чтобы завершить манипуляцию.

    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. В класс MainWindow добавьте следующий обработчик событий ManipulationInertiaStarting.

    Событие ManipulationInertiaStarting возникает, когда пользователь отрывает от экрана все пальцы. Код устанавливает исходную скорость и замедление для движения, расширения и поворота прямоугольника.

    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. Выполните построение и запуск проекта.

    В окне должен появиться красный квадрат.

Тестирование приложения

Чтобы протестировать приложение, попытайтесь выполнить следующие манипуляции. Следует отметить, что одновременно можно выполнять несколько приведенных ниже действий.

  • Чтобы переместить объект Rectangle, поместите палец на Rectangle и перемещайте его по экрану.

  • Чтобы изменить размер объекта Rectangle, поместите два пальца на Rectangle и перемещайте пальцы ближе друг к другу или дальше друг от друга.

  • Чтобы повернуть объект Rectangle, поместите два пальца на Rectangle и поворачивайте пальцы друг вокруг друга.

Чтобы вызвать инерцию, быстро оторвите пальцы от экрана во время выполнения предыдущих манипуляций. Объект Rectangle будет продолжать перемещаться, изменять размер или поворачиваться еще несколько секунд, прежде чем остановится.

См. также

Ссылки

UIElement.ManipulationStarting

UIElement.ManipulationDelta

UIElement.ManipulationInertiaStarting