연습: 첫 번째 터치 애플리케이션 만들기

WPF 응용 프로그램에서 터치에 응답할 수 있습니다. 예를 들어 터치 터치 장치에서 하나 이상의 손가락을 사용 하 여 응용 프로그램과 상호 작용할 수 있습니다 .이 연습에서는 사용자가 터치를 사용 하 여 단일 개체를 이동 하거나 크기를 조정 하거나 회전할 수 있는 응용 프로그램을 만듭니다.

필수 구성 요소

이 연습을 완료하려면 다음과 같은 구성 요소가 필요합니다.

  • Visual Studio.

  • 터치 스크린 등 Windows Touch를 지 원하는 터치 입력을 허용 하는 장치입니다.

또한에서 응용 프로그램을 만드는 방법 WPF , 특히 이벤트를 구독 하 고 처리 하는 방법에 대 한 기본적인 이해가 있어야 합니다. 자세한 내용은 연습: 내 첫 WPF 데스크톱 응용 프로그램을 참조 하세요.

애플리케이션 작성

애플리케이션을 만들려면

  1. Visual Basic 또는 Visual C#에서 BasicManipulation이라는 새 WPF 애플리케이션 프로젝트를 만듭니다. 자세한 내용은 연습: 내 첫 WPF 데스크톱 응용 프로그램을 참조 하세요.

  2. Mainwindow.xaml의 내용을 다음 XAML로 바꿉니다.

    이 태그는에 빨강을 포함 하는 간단한 응용 프로그램을 만듭니다 Rectangle Canvas . IsManipulationEnabled의 속성은 Rectangle true로 설정 되어 조작 이벤트를 수신 합니다. 응용 프로그램은 ManipulationStarting , ManipulationDelta 및 이벤트를 구독 ManipulationInertiaStarting 합니다. 이러한 이벤트에는 사용자가 조작할 때를 이동 하는 논리가 포함 되어 Rectangle 있습니다.

    <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. Visual Basic를 사용 하는 경우 Mainwindow.xaml의 첫 번째 줄에서을 x:Class="BasicManipulation.MainWindow" 로 바꿉니다 x:Class="MainWindow" .

  4. 클래스에 MainWindow 다음 이벤트 처리기를 추가 합니다 ManipulationStarting .

    ManipulationStarting이 이벤트는 WPF 가 터치식 입력이 개체를 조작 하기 시작 하는 것을 감지할 때 발생 합니다. 코드는 속성을 설정 하 여 조작 위치가에 상대적인 지 여부를 지정 합니다 Window 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. 클래스에 MainWindow 다음 이벤트 처리기를 추가 합니다 ManipulationDelta .

    ManipulationDelta 이벤트는 터치 입력의 위치가 변경 되 고 조작 하는 동안 여러 번 발생할 수 있는 경우에 발생 합니다. 이 이벤트는 손가락이 발생 한 후에도 발생할 수 있습니다. 예를 들어 사용자가 화면을 가로질러 손가락을 끌면 ManipulationDelta 손가락 이동 시 이벤트가 여러 번 발생 합니다. 사용자가 화면에서 손가락을 발생 시키면 ManipulationDelta 이벤트는 관성을 시뮬레이션 하기 위해 계속 해 서 발생 합니다.

    이 코드는 DeltaManipulation RenderTransform Rectangle 사용자가 터치 입력을 이동할 때를 이동 하기 위해의에를 적용 합니다. 또한 Rectangle 관성 중에 이벤트가 발생 하는 경우가의 범위 밖에 있는지 여부를 확인 합니다 Window . 그렇다면 응용 프로그램은 메서드를 호출 ManipulationDeltaEventArgs.Complete 하 여 조작을 종료 합니다.

    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. 클래스에 MainWindow 다음 이벤트 처리기를 추가 합니다 ManipulationInertiaStarting .

    ManipulationInertiaStarting 이벤트는 사용자가 화면에서 모든 손가락을 발생 시킬 때 발생 합니다. 이 코드는 사각형의 이동, 확장 및 회전에 대 한 초기 속도와 감속을 설정 합니다.

    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. 프로젝트를 빌드하고 실행합니다.

    창에 빨간색 사각형이 표시 됩니다.

애플리케이션 테스트

응용 프로그램을 테스트 하려면 다음 조작을 시도 합니다. 다음 중 한 번에 둘 이상의 작업을 수행할 수 있습니다.

  • 를 이동 하려면에 Rectangle 손가락을 놓고 화면에서 Rectangle 손가락을 이동 합니다.

  • 크기를 조정 하려면에 Rectangle 두 손가락을 놓고 Rectangle 손가락을 서로 가까운 거리에 이동 합니다.

  • 을 회전 하려면에 Rectangle 두 손가락을 놓고 Rectangle 손가락을 서로 회전 합니다.

관성을 발생 시키려면 이전 조작을 수행 하면서 화면에서 손가락을 빠르게 올립니다. 는 Rectangle 중지 되기 전에 몇 초 동안 계속 이동, 크기 조정 또는 회전 됩니다.

참고 항목